gpt4 book ai didi

ruby - 轻松创建枚举器

转载 作者:数据小太阳 更新时间:2023-10-29 07:59:17 25 4
gpt4 key购买 nike

当创建yield 的方法时,如果没有给出 block ,有时我们希望它返回一个Enumeratorrecommended 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 修改现有方法,这与 protectedprivate 非常相似public 方法。请注意,这些可见性方法以以下形式使用:

protected
def foo; ... end

protected def foo; ... end

def foo; ... end
protected :foo

后两种方式在您的make_enum 中已经可用。特别是,第二种形式已经成为可能(Stefan 在评论中也提到了这一点)。你可以这样做:

make_enum def test; ... end

如果你想做第一种形式,你应该尝试在你的 make_enum 定义中实现它。

关于ruby - 轻松创建枚举器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31865023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com