创建yield
的方法时,如果没有给出块,有时我们希望它返回Enumerator
。 recommended 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}}之类的。
答案 0 :(得分:3)
尽管attr_
方法新创建了实例方法,但您的make_enum
修改了现有方法,该方法与protected
,private
和public
方法非常相似。请注意,这些可见性方法使用以下形式:
protected
def foo; ... end
或
protected def foo; ... end
或
def foo; ... end
protected :foo
后两种方式已经可用于make_enum
。特别是,第二种形式已经成为可能(Stefan也在评论中指出)。你可以这样做:
make_enum def test; ... end
如果您想要填写第一个表单,请尝试在make_enum
定义中实现该表单。