我有一个数组,我不断在不同的时间点添加代码块。当特定事件发生时,迭代器遍历此数组并一个接一个地生成块。
其中许多块都是相同的,我想避免执行重复的块。
这是示例代码:
@after_event_hooks = []
def add_after_event_hook(&block)
@after_event_hooks << block
end
@after_event_hooks.uniq
或@after_event_hooks |= block
之类的内容无效。
有没有办法比较块或检查它们的唯一性?
答案 0 :(得分:2)
无法检查块的唯一性,因为这将意味着检查它们是否代表相同的功能,这是不可能的,并且已经在计算机科学中研究了很长时间。
您可以使用类似于“Ruby block to string instead of executing”中讨论的函数,这是一个函数,它接受一个块并返回块中代码的字符串表示,并比较字符串的输出接收。
我不确定这是否足够快,值得比较它们,而不是多次执行它们。这也有你需要确保代码完全相同的缺点,即使一个具有不同名称的变量也会破坏它。
答案 1 :(得分:0)
正如@hakcho所说,比较块并不是一件容易的事。一个简单的解决方案可能是对命名挂钩的API请求,因此您可以比较名称:
@after_event_hooks = {}
def add_after_event_hook(name, &block)
@after_event_hooks[name] = block
end
def after_event_hooks
@after_event_hooks.values
end
答案 2 :(得分:0)
也许使用这样的东西:
class AfterEvents
attr_reader :hooks
def initialize
@hooks = {}
end
def method_missing(hook_sym, &block)
@hooks[hook_sym] = block
end
end
以下是一个示例:
events = AfterEvents.new
events.foo { puts "Event Foo" }
events.bar { puts "Event Bar" }
# test
process = {:first => [:foo], :sec => [:bar], :all => [:foo, :bar]}
process.each { |event_sym, event_codes|
puts "Processing event #{event_sym}"
event_codes.each { |code| events.hooks[code].call }
}
# results:
# Processing event first
# Event Foo
# Processing event sec
# Event Bar
# Processing event all
# Event Foo
# Event Bar