help on the dummy module

R

Ruby Newbee

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.
 
R

Rick DeNatale

module ShiftMeansAppend
=A0def <<(x) =A0#1
=A0end
end
class String
=A0include ShiftMeansAppend
end
class Array
=A0include ShiftMeansAppend
end
def append_to_self(x)
=A0unless x.is_a? ShiftMeansAppend =A0#2
=A0 =A0raise ArgumentError, "I can't trust this object's left-shift opera= tor."
=A0end
=A0x << 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 strin=
g?

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 =3D Object.new
=3D> #<Object:0x00000101176068>
ruby-1.9.1-p376 > a.kind_of? Object
=3D> true
ruby-1.9.1-p376 > a.kind_of? Kernel
=3D> true
ruby-1.9.1-p376 > a.kind_of? Comparable
=3D> 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
=3D> #<Object:0x00000101176068>
ruby-1.9.1-p376 > a.kind_of? Comparable
=3D> 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
=3D> [1, 2, 3, [...]]

ruby-1.8.6-p383 > [1, 2, 3] << [1, 2, 3]
=3D> [1, 2, 3, [1, 2, 3]]
ruby-1.8.6-p383 > ([1, 2, 3] << [1, 2, 3]).flatten
=3D> [1, 2, 3, 1, 2, 3]
ruby-1.8.6-p383 > [1, 2, 3].append_to_self
=3D> [1, 2, 3, [...]]
ruby-1.8.6-p383 > [1, 2, 3].append_to_self.flatten
ArgumentError: tried to flatten recursive array


--=20
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
 
R

Ruby Newbee

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top