Sam Roberts wrote:
Quoteing eero.saynatkari@kolumbus.fi, on Wed, Jan 26, 2005 at 07:51:57AM +0900:
Lähettäjä: "George Moschovitis" <george.moschovitis@gmail.com>
Aihe: Re: Injecting methods from one class into another.I do not think what you want has anything to do with 'duck typing'.
You're forgetting something. It's not "If it quacks...", it's
"If it quacks... and if it walks...". The gist is that as long as
an object has *all* of the (required) characteristics of a type, the
object can be treated as a specimen of that type.I don't think thats the case at all. I'd like to see you implement
something that "walks like a Hash" by your definition! Make sure you
do all of:==, , =, clear, default, default=, default_proc, delete,
delete_if, each, each_key, each_pair, each_value, empty?, fetch,
has_key?, has_value?, include?, index, indexes, indices,
initialize_copy, inspect, invert, key?, keys, length, member?,
merge, merge!, rehash, reject, reject!, replace, select, shift,
size, sort, store, to_a, to_hash, to_s, update, value?, values,
values_atAnd there is no "HashWalk" module you can include to make your class
walk like a Hash, so you might have to copy all those methods...Yet, there are many objects that are sufficiently like a Hash that you
can use that object in place of a Hash, in particular circumstances. I'd
say that's the more common use of duck-typing.
That's what I said
If the only requirement one has of a duck is the ability to fly, then for
all intents and purposes, a hawk is a duck. Signor Moschovitis, however,
was essentially claiming that since a hawk can fly and a duck can fly, a
hawk must be a duck (or, if an object responds to one of the methods of
a given type, it should somehow be able to respond to all the others as well).
Duck typing, essentially, means that, /in a particular context/, a
given object has all the characteristics of a given type. For example,
it might be enough for an object to implement and = for it to be
treated as a Hash in a certain context.
As an animal analogy regarding 'injecting' methods, tearing off the
wings of a duck and gluing them to a pig doesn't mean the pig can fly.There are methods in library classes I would like in my classes. Right
now, I cut and paste. Yes, if those methods were in a module, I could
include them, but they are not. Would "method stealing" always work? Of
course not. But, the methods I want would work!This is a real example, the specific methods I have copied are from
resolv.rb, DNS#getaddress() ... DNS#getresources() I have copied (I have
my own #each_resource()).I may try to inherit. But, my class relationship to DNS does NOT model
a "is a" relationship. So, I am abusing inheritance to steal
implementation. Is this so beautiful?Also, there are methods I don't want, I need to make sure they do not
appear. Also, there are constants that must have a different value in my
class, can I change them? I don't think so.Really, I just want those methods! But, there is no way to get them in
my class other than copying, or convincing the maintainer to cut his
class into pieces for me. Too bad.
I can see your point: however, a circumstance like this is somewhat exceptional.
Usually such is not possible due to method dependencies or missing variables
or whatever. The 'proper' thing to do would be to factor out such common code
and implement a Module (e.g. Enumerable) with the desired functionality. If
you can't factor it out, it means the implementation should remain separate.
Ruby is still better than the alternatives.
Thanks,
Sam
E