[ANN] Ducktator - A Duck Type Validator

O

Ola Bini

Announcing the first release of Ducktator, a Duck Type validator.

Ducktator is a small library to enable Ruby systems to generically
validate objects introspectively. In plain speak, check certain common
methods of objects, and see if they match what your schema expects the
values to be. This capability is not necessary for most applications,
but sometimes it's highly useful. For example, validating objects that
have been serialized or marshallad. Validating what you get when
loading YAML files, so that the object graph matches what your code
does. Write test cases that expect a complicated object back. The
possibilities are many.

Ducktator can be configured either with YAML or directly using simple
Hashes. The syntax is very recursive, extensible and easy. I will use
YAML for the examples in this document, but for easier validations it
may be better just creating the +Hash+ directly.

The project resides at http://rubyforge.org/projects/ducktator
It can be installed by gems:
gem install ducktator

More information can be found in the RDoc and README, and here:
http://ola-bini.blogspot.com/2006/09/announcing-ducktator-duck-type.html

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
J

Jonas Pfenniger

Hi,

just. Isn't checking classes not very ducktyping-alike or did I miss something ?
 
O

Ola Bini

Eric said:
Why in the world do you think this is a "Duck Type validator"? You are
trying to do static type checking in ruby which is the exact opposite of
duck typing. You say this in your blog:

"As I hinted in my last post, I feel with all my heart that there should be
some way to actively validate my static expectations on certain kinds of
objects."

Don't go try and change the meaning of duck typing to something
analogous to
static typing! Duck typing already has enough meanings...

Actually, the name is more about the fact that you can use regular
duck-type techniques (like respond_to?), combine these in ways that are
not feasible/practical in code, and validate against this. As I also say
in the documentation. This is not a good fit for most situations, but
some applications need it. In my mind, testing is probably the best bet,
where you need to see if you got back what you expect.

If I want to see, in duck typing language, if I've gotten an argument
which has an each method which yields objects that all respond to :foo,
this is still duck typing, neh? But it's not really practical to code
all over the place. These are the situations Ducktator is for.

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
J

Jonas Pfenniger

I'm sure this can be extended to support a hierarchy :

class Object
def quaks_like?(*args)
args.each do |a|
return false unless respond_to? a
end
return true
end
end

x = {}
x.quaks_like? :to_hash, :each, :merge #=> true
 
O

Ola Bini

Jonas said:
I'm sure this can be extended to support a hierarchy :

class Object
def quaks_like?(*args)
args.each do |a|
return false unless respond_to? a
end
return true
end
end

x = {}
x.quaks_like? :to_hash, :each, :merge #=> true

Oh yes. You could, but on the other hand you would have to write code
like that if you want it somewhere else. Or, if you want something that
checks another aspect. Actually, the validator is really for the more
convoluted cases, where you still need validity of some kind. If your
objects always are in your control, sure, or if you want to sprinkle
your code with respond_to?'s all over, that's fine, just do that. I feel
the need for this when I load huge YAML documents with nested structure,
or when receiving something through SOAP, that I need to test out. For
example. This isn't static type safety, nor anywhere close. But it lets
you fail fast of the object doesn't match.

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
J

Jonas Pfenniger

Oh yes. You could, but on the other hand you would have to write code
like that if you want it somewhere else. Or, if you want something that
checks another aspect. Actually, the validator is really for the more
convoluted cases, where you still need validity of some kind. If your
objects always are in your control, sure, or if you want to sprinkle
your code with respond_to?'s all over, that's fine, just do that. I feel
the need for this when I load huge YAML documents with nested structure,
or when receiving something through SOAP, that I need to test out. For
example. This isn't static type safety, nor anywhere close. But it lets
you fail fast of the object doesn't match.

Yeah so your project is more a YAML DTD. It uses duck-typing but also
class validation.
 
O

Ola Bini

Jonas said:
Yeah so your project is more a YAML DTD. It uses duck-typing but also
class validation.

Nope. YAML schema is another thing entirely. This is for Ruby only. And,
no, it doesn't _use_ class validation, but the _user_ of it can use
class validation, if he/she/it feels it's necessary.

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
P

Pit Capitain

Ola said:
Announcing the first release of Ducktator, a Duck Type validator.

Ola, do you know ruby-contract, also on rubyforge? I haven't used it
yet, but I think Florian uses Ruby code in the form of unit tests to
specify the desired behaviour.

Regards,
Pit
 
L

Leslie Viljoen

This might be useful in testing. Thanks for the hard work! I can
imagine a scheme where during debugging I do exhaustive validation of
all objects passed to each method. This way I know if the object
doesn't respond to a method - I don't have to wait for a call to fail.

Incidentally, I have often wondered if there might be a tool that
could generate a report of the methods a certain method might try to
call on a specific object. For example:

def doSomethingAmazing(fridgeMagnet, pieceOfString, brownPaperBag)
pieceOfString.tie fridgeMagnet, brownPaperBag[5]
pieceOfString.unravel
fridgeMagnet.stickTo self.fridge
end

.. produces ..

doSomethingAmazing
--------------------------------
fridgeMagnet: stickTo
pieceOfString: tie, unravel
brownPaperBag: [


.. so if I am implementing an object to pass to doSomethingAmazing, I
know what it expects.

Les
 
M

MonkeeSage

Hi Ola,

Thanks for your efforts. I have several uses in mind for this already.
:)

Ps. I think people are confusing the idea of C-types (primatives) with
the idea of "types" in category theory (e.g., ML types, i.e., object
signatures). Your library seems like a logical extension of duck-typing
to me; if it walks like a duck and talks like a duck (which your
library will ensure), then for all intents and purposes, it is a duck;
who cares about what kind of primative it is!

Regards,
Jordan
 
O

Ola Bini

MonkeeSage said:
Hi Ola,

Thanks for your efforts. I have several uses in mind for this already.
:)

Ps. I think people are confusing the idea of C-types (primatives) with
the idea of "types" in category theory (e.g., ML types, i.e., object
signatures). Your library seems like a logical extension of duck-typing
to me; if it walks like a duck and talks like a duck (which your
library will ensure), then for all intents and purposes, it is a duck;
who cares about what kind of primative it is!

Regards,
Jordan

Hi,

Thanks very much for clarifying. This is exactly the intent I had in mind!

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
R

Robert Klemme

I'm sure this can be extended to support a hierarchy :

class Object
def quaks_like?(*args)
args.each do |a|
return false unless respond_to? a
end
return true
end
end

def quacks_like?(*args)
args.all? {|a| respond_to? a}
end

SCNR :)

robert
 
R

Robert Klemme

Actually, the name is more about the fact that you can use regular
duck-type techniques (like respond_to?),

I do not think that the use of respond_to? is a regular duck typing
technique. As Eric put it, respond_to? is exactly not applied regularly
when duck typing.

Don't get me wrong, I don't say your lib is useless (in fact I envision
numerous uses for test cases etc.) but I think this claim of yours is wrong.

Kind regards

robert
 
M

MonkeeSage

Robert said:
I do not think that the use of respond_to? is a regular duck typing
technique. As Eric put it, respond_to? is exactly not applied regularly
when duck typing.

Don't get me wrong, I don't say your lib is useless (in fact I envision
numerous uses for test cases etc.) but I think this claim of yours is wrong.

Not to push the issue, but Wikipedia seems to think that this is a
valid claim [1]:

"[...A]n object having all the methods described in an interface can be
made to implement that interface dynamically at runtime, even if the
object's class does not include the interface in its implements
clause. It also implies that an object is interchangeable with any
other object that implements the same interface, regardless of whether
the objects have a related inheritance hierarchy."

respond_to? in ruby is just a dynamic way of checking that "an object
is interchangeable with any other object that implements the same
interface".

[1] http://en.wikipedia.org/wiki/Duck_typing

Regards,
Jordan
 
R

Robert Klemme

Robert said:
I do not think that the use of respond_to? is a regular duck typing
technique. As Eric put it, respond_to? is exactly not applied regularly
when duck typing.

Don't get me wrong, I don't say your lib is useless (in fact I envision
numerous uses for test cases etc.) but I think this claim of yours is wrong.

Not to push the issue, but Wikipedia seems to think that this is a
valid claim [1]:

"[...A]n object having all the methods described in an interface can be
made to implement that interface dynamically at runtime, even if the
object's class does not include the interface in its implements
clause. It also implies that an object is interchangeable with any
other object that implements the same interface, regardless of whether
the objects have a related inheritance hierarchy."

respond_to? in ruby is just a dynamic way of checking that "an object
is interchangeable with any other object that implements the same
interface".

The article does not claim that a client needs to check this. And in
Ruby you generally do not do that either, you just use it. It just
states that it's possible for an object to /dynamically/ implement a
certain interface although it is not declared.

Kind regards

robert
 
O

Ola Bini

Robert said:
Robert said:
I do not think that the use of respond_to? is a regular duck typing
technique. As Eric put it, respond_to? is exactly not applied regularly
when duck typing.

Don't get me wrong, I don't say your lib is useless (in fact I envision
numerous uses for test cases etc.) but I think this claim of yours is
wrong.

Not to push the issue, but Wikipedia seems to think that this is a
valid claim [1]:

"[...A]n object having all the methods described in an interface can be
made to implement that interface dynamically at runtime, even if the
object's class does not include the interface in its implements
clause. It also implies that an object is interchangeable with any
other object that implements the same interface, regardless of whether
the objects have a related inheritance hierarchy."

respond_to? in ruby is just a dynamic way of checking that "an object
is interchangeable with any other object that implements the same
interface".

The article does not claim that a client needs to check this. And in
Ruby you generally do not do that either, you just use it. It just
states that it's possible for an object to /dynamically/ implement a
certain interface although it is not declared.

The problem with "just use it", is that you will have no control over
error handling in this case. In most situations, the error is the
programmers, in which case it doesn't matter, but when reading in
something you're not entirely sure what it is, it's better to be able to
report consistently what's wrong to the user instead of failing randomly
with a method_missing in the middle of nowhere.

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 
A

Austin Ziegler

Actually, the name is more about the fact that you can use regular
duck-type techniques (like respond_to?),

Note: if you're calling #respond_to? you're not doing duck typing.
You're doing contract validation, perhaps, but not duck typing. Duck
typing is just calling a method and expecting that it will be
implemented. It's *trusting* your callers to do the right thing.

Now, I sometimes use #respond_to? -- but it isn't duck typing.

Additionally, if it's an external validation suite -- I haven't looked
at the project -- it isn't really checking against live code.

-austin
 
A

Austin Ziegler

The problem with "just use it", is that you will have no control over
error handling in this case.

This is demonstrably untrue. Duck typing is not about validation. It's
about trusting your callers to do the right thing -- and then doing
the right thing when they don't.

-austin
 
O

Ola Bini

Austin said:
Note: if you're calling #respond_to? you're not doing duck typing.
You're doing contract validation, perhaps, but not duck typing. Duck
typing is just calling a method and expecting that it will be
implemented. It's *trusting* your callers to do the right thing.

Now, I sometimes use #respond_to? -- but it isn't duck typing.

Additionally, if it's an external validation suite -- I haven't looked
at the project -- it isn't really checking against live code.

-austin

I beg to differ, and according to the pick-axe, this interpretation is
correct. Duck-typing isn't to *trust* your callers. Duck typing is to
check if something quacks like a duck and walks like a duck. Well, me
calling respond_to? checks if the object quacks and walks. What you are
describing isn't a technique, it is the absence of a technique.

--
Ola Bini (http://ola-bini.blogspot.com)
JvYAML, RbYAML, JRuby and Jatha contributor
System Developer, Karolinska Institutet (http://www.ki.se)
OLogix Consulting (http://www.ologix.com)

"Yields falsehood when quined" yields falsehood when quined.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top