From: Rick DeNatale Date: 2010-01-20T12:46:05+09:00 Subject: Re: help on the dummy module On Tue, Jan 19, 2010 at 10:08 PM, Ruby Newbee wrote: > module ShiftMeansAppend >  def <<(x)  #1 >  end > end > class String >  include ShiftMeansAppend > end > class Array >  include ShiftMeansAppend > end > def append_to_self(x) >  unless x.is_a? ShiftMeansAppend  #2 >    raise ArgumentError, "I can't trust this object's left-shift operator." >  end >  x << x > end > > > Hello, > > For the code above, I can't understand that: > > #1 why redefine "<<" and set its action to nothing? > #2 why x.is_a? ShiftMeansAppend can be true when x is an array or a string? Because, it seems to me, that the author of that code sees Ruby through Java colored classes and doesn't understand Ruby all that well. I see that the code comes from a Ruby Cookbook book, and is discussing how to not use duck-typing. He's trying to do the equivalent of the technique in Java of using an interface as a marker. #1 is totally unnecessary, Since String and Array both have #<< methods, and classes are searched for methods before any modules they include, the method in the module will never be invoked. It seems that the author thinks that like Java a method needs to be defined in an interface or a superclass to be considered the same method. Not so in Ruby which doesn't have interfaces. Modules just add methods to the repertoire of an objects instances. #2 is_a? tests whether the argument is anywhere on the chain of classes and modules which are on chain searched for an objects methods. So x.is_a? y is true if y is the class of x, or on the chain of superclasses of that class, or a module included by one of those classes ruby-1.9.1-p376 > a = Object.new => # ruby-1.9.1-p376 > a.kind_of? Object => true ruby-1.9.1-p376 > a.kind_of? Kernel => true ruby-1.9.1-p376 > a.kind_of? Comparable => false It also returns true for a module if the singleton class of the object includes the module, which can be accomplshed with the Object#extend method ruby-1.9.1-p376 > a.extend Comparable => # ruby-1.9.1-p376 > a.kind_of? Comparable => true The motivating example a function which takes an object and appends it to itself is rather strained, IMHO. Personally I'd never be tempted to write such a method. Rather I'd implement it on String and Array module SelfAppendable def append_to_self self << self end end class String include SelfAppendable end class Array include SelfAppendable end And I don't know if the Author really expects the result of appending an Array to itself, inserting a element into an Array with << inserts a reference to the element, so this will generate a recursive array, which can cause problems. ruby-1.8.6-p383 > [1, 2, 3].append_to_self => [1, 2, 3, [...]] ruby-1.8.6-p383 > [1, 2, 3] << [1, 2, 3] => [1, 2, 3, [1, 2, 3]] ruby-1.8.6-p383 > ([1, 2, 3] << [1, 2, 3]).flatten => [1, 2, 3, 1, 2, 3] ruby-1.8.6-p383 > [1, 2, 3].append_to_self => [1, 2, 3, [...]] ruby-1.8.6-p383 > [1, 2, 3].append_to_self.flatten ArgumentError: tried to flatten recursive array -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale