# Help on the dummy module

**URL:** <https://www.ruby-forum.com/t/help-on-the-dummy-module/181911>\
**Category:** Ruby\
**Created:** [January 20, 2010, 4:09am UTC](https://www.ruby-forum.com/t/help-on-the-dummy-module/181911 "2010-01-20T04:09:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubynut](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e8cbc/32.png) [@rubynut](https://www.ruby-forum.com/u/rubynut)\
**Post date:** [January 20, 2010, 4:09am UTC](https://www.ruby-forum.com/t/help-on-the-dummy-module/181911/1 "2010-01-20T04:09:20Z")

</div>

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?

Thanks.

---

<div class="post-metadata">

**Author:** ![rubynut](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e8cbc/32.png) [@rubynut](https://www.ruby-forum.com/u/rubynut)\
**Post date:** [January 20, 2010, 4:48am UTC](https://www.ruby-forum.com/t/help-on-the-dummy-module/181911/2 "2010-01-20T04:48:32Z")

</div>

On Tue, Jan 19, 2010 at 10:08 PM, Ruby N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> def append\_to\_self(x)
> 
> #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  
=\> #Object:0x00000101176068  
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  
=\> #Object:0x00000101176068  
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/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [Rick DeNatale - Developer - IBM | LinkedIn](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![rubynut](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e8cbc/32.png) [@rubynut](https://www.ruby-forum.com/u/rubynut)\
**Post date:** [January 20, 2010, 6:39am UTC](https://www.ruby-forum.com/t/help-on-the-dummy-module/181911/3 "2010-01-20T06:39:09Z")

</div>

Thanks RIck for the great explaining.  
I was also strange for this behavior:

irb(main):001:0\> x=[1,2,3]  
=\> [1, 2, 3]  
irb(main):002:0\> x\<\<x  
=\> [1, 2, 3, […]]  
irb(main):003:0\> x[-1]  
=\> [1, 2, 3, […]]  
irb(main):006:0\> x[-1][-1]  
=\> [1, 2, 3, […]]

Now under your helps I have got it.

Thanks.
