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.
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...
···
On 9/19/06, Ola Bini <ola.bini@ki.se> wrote:
Announcing the first release of Ducktator, a Duck Type validator.
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.
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:
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.
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!
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.
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!
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
···
On 19.09.2006 21:12, Ola Bini 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/19/06, Ola Bini <ola.bini@ki.se> wrote:
Actually, the name is more about the fact that you can use regular
duck-type techniques (like respond_to?),
Yeah so your project is more a YAML DTD. It uses duck-typing but also
class validation.
···
On 19/09/06, Ola Bini <ola.bini@ki.se> 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.
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".
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
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.
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.
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.
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.