轻松创建枚举器
Easily create an Enumerator
在创建 yield
的方法时,有时我们希望它 return 一个 Enumerator
如果没有给出块。 recommended way 基本上是 return to_enum(:name_of_method, [args]) unless block_given?
。但是,必须为每个执行此操作的方法键入它是一件痛苦的事情。 Ruby 是 ruby,我决定创建一个 make_enum
方法,类似于 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
?
class Test
make_enum :test
def test
yield 1
yield 2
end
end
我不知道把它放在方法之前是否是个坏主意,但我认为这样做会很好的原因是它更符合我们使用的方式 attr_accessor
等等。
虽然 attr_
方法新创建实例方法,但您的 make_enum
修改现有方法,这与 protected
、private
和 [=18= 非常相似] 方法。请注意,这些可见性方法以以下形式使用:
protected
def foo; ... end
或
protected def foo; ... end
或
def foo; ... end
protected :foo
您的 make_enum
已经可以使用后两种方式。特别是,第二种形式已经成为可能(Stefan 在评论中也提到了这一点)。你可以这样做:
make_enum def test; ... end
如果你想做第一种形式,你应该尝试在你的 make_enum
定义中实现它。
在创建 yield
的方法时,有时我们希望它 return 一个 Enumerator
如果没有给出块。 recommended way 基本上是 return to_enum(:name_of_method, [args]) unless block_given?
。但是,必须为每个执行此操作的方法键入它是一件痛苦的事情。 Ruby 是 ruby,我决定创建一个 make_enum
方法,类似于 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
?
class Test
make_enum :test
def test
yield 1
yield 2
end
end
我不知道把它放在方法之前是否是个坏主意,但我认为这样做会很好的原因是它更符合我们使用的方式 attr_accessor
等等。
虽然 attr_
方法新创建实例方法,但您的 make_enum
修改现有方法,这与 protected
、private
和 [=18= 非常相似] 方法。请注意,这些可见性方法以以下形式使用:
protected
def foo; ... end
或
protected def foo; ... end
或
def foo; ... end
protected :foo
您的 make_enum
已经可以使用后两种方式。特别是,第二种形式已经成为可能(Stefan 在评论中也提到了这一点)。你可以这样做:
make_enum def test; ... end
如果你想做第一种形式,你应该尝试在你的 make_enum
定义中实现它。