In Ruby 1.8, what's the magic incantation so that I can do
x = X.new
x.each {|y| puts y}
You can do that anyway, it just doesn't do anything. All methods can accept a
block, whether you want them to or not. All you have to do is yield to it.
I have read and reread Dave Thomas'*Programming Ruby 1.9* and ... well ...
I think I have to define *each* in class X and add some enumerable stuff
First, why are you reading a 1.9 book and applying it to 1.8?
Not that it should matter...
You have to define 'each', yes, and you probably should include enumerable.
I'll give a contrived solution to your contrived example:
class X
def each
yield @x[0]
yield @x[1]
...
end
end
That 'yield' is a call to whatever block you passed. You could, of course,
wrap it in a loop, or even an enumerator of its own:
class X
def each
@x.each {|x| yield x}
end
end
In this specific case, your contrived example is just contrived enough that we
could take it a step further. You can grab that block as an actual argument by
prefixing it with &, and apply it the same way. So, you can just pass it
straight through, as Michael Fellinger suggested:
class X
def each(&block)
@x.each(&block)
end
end
It's contrived, but we may as well finish it up:
class X
# adds map, select, and so on
include Enumerable
def each(&block)
# enum_for makes a new enum which uses 'each' by default
return enum_for if block_given?
@x.each(&block)
end
end
I don't always include Enumerable, but I do always do enum_for, because not
everything I want to enumerate is already in a form I can call 'each' on. For
example:
class Foo
def all_bars
return enum_for :all_bars unless block_given?
yield :bar
yield :foobar
yield :baz
end
end
Now I can do crazy stuff like:
Foo.new.all_bars.map(&:to_s)
Foo.new.all_bars{|b| puts b}
That way, I can have multiple methods like that, each of which either behaves
as the appropriate iterator, or gives me an appropriate enumerable (an
enumerator, specifically) to play with.
I just don't get it.
I hope I've helped, but if not, I'm going to need more than that. If you still
don't get it, let me know what you don't get, and we can go from there.
···
On Saturday, August 21, 2010 12:45:49 pm Ralph Shnelvar wrote: