Identify unique blocks
我有一个数组,我在不同的时间点不断向其中添加代码块。当特定事件发生时,迭代器会遍历此数组并一个接一个地产生块。
其中许多块是相同的,我想避免执行重复的块。
这是示例代码:
1 2 3 4 5 | @after_event_hooks = [] def add_after_event_hook(&block) @after_event_hooks << block end |
像
有没有办法比较块或检查它们的唯一性?
无法检查块的唯一性,因为这意味着检查它们是否代表相同的功能,这是不可能的,并且已经在计算机科学中研究了很长时间。
您可能可以使用类似于"Ruby 块到字符串而不是执行"中讨论的函数,该函数接受块并返回块中代码的字符串表示,并比较输出您收到的字符串。
我不确定这是否足够快以值得比较它们,而不是多次执行它们。这也有一个缺点,您需要确保代码完全相同,即使一个具有不同名称的变量也会破坏它。
也许使用这样的东西:
1 2 3 4 5 6 7 8 9 10 11 | class AfterEvents attr_reader :hooks def initialize @hooks = {} end def method_missing(hook_sym, &block) @hooks[hook_sym] = block end end |
这是一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
正如@hakcho 所说,比较块并非易事。一个简单的解决方案可能是对命名挂钩的 API 请求,因此您可以比较名称:
1 2 3 4 5 6 7 8 9 | @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 |