On 2/17/07, Yukihiro Matsumoto <matz / ruby-lang.org> wrote:
> Hi,
>
> In message "Re: Oppinions on RCR for dup on immutable classes"
>     on Sat, 17 Feb 2007 22:51:06 +0900, Stefan Rusterholz <apeiros / gmx.net> writes:
>
> |With current implementation, the only way to figure if an object can be
> |dup'ed is by dup it and catch the exception. I don't know how imperative
> |duck-typing is for ruby, but this way actively prohibits it.
>
> As far as I understand, DuckTyping is not something based on method
> existence, but something letting them raise error without explicit
> type checking.
>
> |As said before, the issue can be worked around (as you say e.g. via
> |exception handling), but following your argument, my question would be:
> |why implement a method that can't be executed?
>
> We haven't implemented a method that can't be executed.  Object#dup
> just fails if the object is not able to be duped.  Am I missing
> something?
>
>                                                         matz.

For me, this does break the POLS, because it breaks the Liskov
Substitution Principle (loosely, "an object of a derived type can be
substituted for an object of a base type", for those of you who
haven't heard of it...). LSP is essentially the underpinnings of
Bertrand Meyer's "Design by Contract".

If I'm iterating through a collection of objects and all of them
respond_to? a method, yet an exception is thrown in some cases, that's
surprising ;)  The deep-copy scenario is a good one. In this case, it
would be nice to have a succinct way of copying the object graph
without having to worry about some dup methods "not working". Perhaps
the "another" method suggestion would work. Perhaps thinking through
all the scenarios of why you would dup an object would suggest
refinements to its behavior. Off hand, I'm wondering if it would be so
bad for an immutable object, like a Fixnum, to allow a.object_id? ==
a.dup.object_id?.

I'm probably missing some important points, as I don't know the
intricasies of Ruby as well as many of you do. This is a typical
dilemma with rich base classes and modules. Occasionally, the rich
"contract" can't be satisfied transparently by all derivatives. Maybe
that's just the price we have to pay for being rich ;)

Dean Wampler
http://www.objectmentor.com
http://www.aspectprogramming.com
http://www.contract4j.org