Easy to create an enumerator

When creating methods that yield

, sometimes we want it to return Enumerator

if no block is specified. The recommended way is mostly return to_enum(:name_of_method, [args]) unless block_given?

. However, it is a pain to be recruited for every method that does it. Ruby was ruby, I decided to create a method make_enum

similar to attr_accessor

which does this for me:

class Module # Put this in a mixin, but for the purposes of this experiment, it 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 this:

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

before the method is defined.

How can I get this method to work before the method is defined so that the following will work? Perhaps I need to use method_added

?

class Test
  make_enum :test

  def test
    yield 1
    yield 2
  end
end

      


I don't know if it was a bad idea for this before the method, but my reason for thinking it would be good to do this is because it better matches the way we use attr_accessor

and the like.

+3


source to share


1 answer


While the methods attr_

create instance methods again, yours is make_enum

modifying the existing method, which is quite similar to methods protected

, private

and public

. Note that these visibility methods are used either in the form:

protected
def foo; ... end

      

or



protected def foo; ... end

      

or



def foo; ... end
protected :foo

      

The last two methods are already available with yours make_enum

. In particular, the second form is already possible (which is also noted by Stefan in the commentary). You can do:

make_enum def test; ... end

      

If you want to make the first shape, you should try to implement it in your definition make_enum

.

+3


source







All Articles