Ducktator - A Duck Type Validator

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:


Ola B. (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.

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…

Hi,

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


Cheers,
zimbatm

Eric M. wrote:

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 B. (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.

Jonas P. wrote:

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 B. (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.

On 19/09/06, Ola B. [email protected] wrote:

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.


Cheers,
zimbatm

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


Cheers,
zimbatm

Jonas P. wrote:

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.

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 B. (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.

This project seem related : http://www.kuwata-lab.com/kwalify/


Cheers,
zimbatm

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

Hi Ola,

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

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

MonkeeSage wrote:

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 B. (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.

On 19.09.2006 21:16, Jonas P. wrote:

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 :slight_smile:

robert

Ola B. schrieb:

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

On 19.09.2006 21:12, Ola B. wrote:

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

Robert K. wrote:

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] Duck typing - Wikipedia

Regards,
Jordan

On 20.09.2006 10:58, MonkeeSage wrote:

“[…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.

[1] Duck typing - Wikipedia

Kind regards

robert

Robert K. wrote:

Not to push the issue, but Wikipedia seems to think that this is a
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 B. (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.

On 9/19/06, Ola B. [email protected] wrote:

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

On 9/20/06, Ola B. [email protected] wrote:

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