Enumerating and mixin

I am trying to learn the correct way to enumerate in Ruby, a few things
are
missing in my 1st stab at this. How do I use mixin with Enumerable to
rewrite
the class I have below? I can’t seem to find a concrete example online?

I know I am also missing code to override <=> if I wanted to do sorting,
are the
other overrides I am missing?

How do I make my code more elegant, Thanks!

class Vowels
def initialize
@index = 0
@list = %w(a e i o u)
end

def each
   while( @index < @list.size )
      if @index >= @list.size
         yield nil
         exit
      else
         yield @list[@index]
         @index += 1
      end
   end
end

def first
   @index=0
end

end

obj = Vowels.new

obj.each { |x| puts x }


Kind Regards,
Rajinder Y.

http://DevMentor.org
Do Good ~ Share Freely

Rajinder Y. wrote:

        exit

end

obj = Vowels.new

obj.each { |x| puts x }

OK I managed to sweet the code down to the following, is there anything
else I
missed?

class Vowels
include Enumerable
def initialize
@list = %w(u e a o i)
end

def each
   @list.each { |item| yield item }
end

end

obj = Vowels.new

obj.each { |s| print s }
puts “”
obj.sort.each { |s| print s }
puts “”


Kind Regards,
Rajinder Y.

http://DevMentor.org
Do Good ~ Share Freely

On 13.10.2009 01:47, Rajinder Y. wrote:

   @list.each { |item| yield item }
end

end

obj = Vowels.new

obj.each { |s| print s }
puts “”
obj.sort.each { |s| print s }
puts “”

Two notes: you can actually pass the block directly on to method each of
Array.

def each(&b)
@list.each(&b)
end

And: conventionally #each returns self.

Taking both together you could do

def each(&b)
@list.each(&b)
self
end

Kind regards

robert

Brian C. wrote:

You mention <=>. This isn’t needed here because each of the elements you
yield is a String, and strings already have <=> and so the elements can
be sorted. But if you want a different exercise, try:

Brian thanks for the demonstration of how to use Comparable, and also
pointing
out the other methods that can be redefined. If you didn’t mention that,
I would
have stopped at <=>. Although I suspect the other methods make use of
<=>
internally?

end

Comparable.instance_methods
=> [“==”, “>=”, “<”, “<=”, “>”, “between?”]

Regards,

Brian.


Kind Regards,
Rajinder Y.

http://DevMentor.org
Do Good ~ Share Freely

Rajinder Y. wrote:

OK I managed to sweet the code down to the following, is there anything
else I
missed?

That’s fine. So far your Vowels class doesn’t really do anything more
than a simple Array would, but you’ve shown how your class gains methods
from the Enumerable module, and you can now add extra functionality
which is specific to a set of vowels. (This is composition by
delegation, an approach I highly recommend)

You mention <=>. This isn’t needed here because each of the elements you
yield is a String, and strings already have <=> and so the elements can
be sorted. But if you want a different exercise, try:

class Vowel
include Comparable
def initialize(v)
@v = v
end
def to_s
@v
end
def <=>(other)
@v <=> other.to_s
end
end

v1 = Vowel.new(“a”)
v2 = Vowel.new(“e”)
v1 < v2 #=> true
v3 = Vowel.new(“e”)
v2 == v3 #=> true

Here you’re exercising a different mixin, Comparable. It takes any class
which implements a <=> operator, and adds these methods for you:

Comparable.instance_methods
=> ["==", “>=”, “<”, “<=”, “>”, “between?”]

Regards,

Brian.

Rajinder Y. wrote:

Brian thanks for the demonstration of how to use Comparable, and also
pointing
out the other methods that can be redefined. If you didn’t mention that,
I would
have stopped at <=>. Although I suspect the other methods make use of
<=>
internally?

That’s exactly what Comparable does: these new methods in turn call the
<=> method that you defined.

In the same way, Enumerable gives you a whole bunch of new methods,
which in turn make use of ‘each’ (and only ‘each’). So as long as you
have defined an ‘each’ method which yields the collection members in
turn, all the other methods in Enumerable will work.

Regards,

Brian.

Robert K. wrote:

puts “”
Taking both together you could do

def each(&b)
@list.each(&b)
self
end

Robert, I didn’t know method each should return self, learned something
to add
to my notes =), also seeing use of &b to denote a code-block drives home
what
I’ve been reading, thanks!

Kind regards

robert


Kind Regards,
Rajinder Y.

http://DevMentor.org
Do Good ~ Share Freely

2009/10/14 Rajinder Y. [email protected]:

Enumerable module, and you can now add extra functionality which is specific
use of <=> internally?
Exactly - as Brian wrote. You can “see” this at work here:

09:45:55 ~$ ruby19 -e ‘class X;include Comparable;def <=>(o);0
end;end;x=X.new;set_trace_func lambda {|*a| p a};x<x’
[“c-return”, “-e”, 1, :set_trace_func, #Binding:0x100a4bb8, Kernel]
[“line”, “-e”, 1, nil, #Binding:0x100a4a78, nil]
[“c-call”, “-e”, 1, :<, #Binding:0x100a499c, Comparable]
[“call”, “-e”, 1, :<=>, #Binding:0x100a4898, X]
[“line”, “-e”, 1, :<=>, #Binding:0x100a47a8, X]
[“return”, “-e”, 1, :<=>, #Binding:0x100a46cc, X]
[“c-return”, “-e”, 1, :<, #Binding:0x1001d744, Comparable]
09:46:07 ~$

Here you’re exercising a different mixin, Comparable. It takes any class
which implements a <=> operator, and adds these methods for you:

Comparable.instance_methods

=> [“==”, “>=”, “<”, “<=”, “>”, “between?”]

Kind regards

robert