When creating methods that yield
, sometimes we want it to return an Enumerator
if no block is given. The recommended way is basically return to_enum(:name_of_method, [args]) unless block_given?
. However, it's a pain to have to type that for every method that does this. Ruby being ruby, I decided to create a make_enum
method, similar to attr_accessor
, which does this for me:
class Module # Put this in a mixin, but for the purposes of this experiment, it's in Module
def make_enum *args
args.each do |name|
old_method = instance_method(name)
define_method(name) do |*args, &block|
next to_enum(name, *args) unless block
old_method.bind(self).call(*args, &block)
end
end
end
end
Now I can use it like so:
class Test
def test
yield 1
yield 2
end
make_enum :test
end
t = Test.new
t.test { |n| puts n }
# 1
# 2
t.test.to_a #=> [1, 2]
And it works! But it doesn't work if make_enum
is before the method definition.
How can I get this method to work before defining a method, so that the following works? Perhaps I need to make use of method_added
?
class Test
make_enum :test
def test
yield 1
yield 2
end
end
I don't know if it's a bad idea for it to be before the method, but my reason for thinking that it would be nice to do that is that it better matches the way we use attr_accessor
and the like.