轻松创建枚举器

时间:2015-08-06 20:18:02

标签: ruby enumerator

创建yield的方法时,如果没有给出块,有时我们希望它返回Enumeratorrecommended way基本上是return to_enum(:name_of_method, [args]) unless block_given?。但是,对于每个执行此操作的方法,必须键入该内容是一件痛苦的事。 Ruby是ruby,我决定创建一个类似于make_enum的{​​{1}}方法,它为我做了这个:

attr_accessor

现在我可以像这样使用它:

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

它有效!但如果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] 在方法定义之前,它就不起作用。

如何在定义方法之前使此方法起作用,以便以下工作?也许我需要使用make_enum

method_added

我不知道它是否在该方法之前是一个坏主意,但我认为这样做很好的原因是它更符合我们使用的方式{{ 1}}之类的。

1 个答案:

答案 0 :(得分:3)

尽管attr_方法新创建了实例方法,但您的make_enum修改了现有方法,该方法与protectedprivatepublic方法非常相似。请注意,这些可见性方法使用以下形式:

protected
def foo; ... end

protected def foo; ... end

def foo; ... end
protected :foo

后两种方式已经可用于make_enum。特别是,第二种形式已经成为可能(Stefan也在评论中指出)。你可以这样做:

make_enum def test; ... end

如果您想要填写第一个表单,请尝试在make_enum定义中实现该表单。