识别独特的块

时间:2016-03-21 12:37:52

标签: ruby

我有一个数组,我不断在不同的时间点添加代码块。当特定事件发生时,迭代器遍历此数组并一个接一个地生成块。

其中许多块都是相同的,我想避免执行重复的块。

这是示例代码:

    @after_event_hooks = []

    def add_after_event_hook(&block)
      @after_event_hooks << block
    end

@after_event_hooks.uniq@after_event_hooks |= block之类的内容无效。

有没有办法比较块或检查它们的唯一性?

3 个答案:

答案 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