我正在编写一个简单的事件总线以在应用程序中使用。这部分工作正常:
#!/usr/bin/env ruby
module EventBus
@callbacks = {}
module_function
def on event, &callback
@callbacks[event] ||= []
@callbacks[event].push callback
end
def fire event, *data
@callbacks[event].each do |callback|
callback.call *data
end
end
end
EventBus.on :foo do |x| puts x end
EventBus.fire :foo, "test"
# => test
由于我的程序的复杂性,以及Proc
s 以非常松散的方式接受参数的事实,我希望对我的事件进行一些参数检查。lambda
是显而易见的选择:
EventBus.on :bar, &(lambda do |x| puts x end)
# Will raise an ArgumentError, since the event was fired without any arguments
# Remember that this is the desired behavior
EventBus.fire :bar
显然,on
由于&(lambda do ... end)
. 我宁愿能够只使用do ... end
(即只需将其传递给没有一元与符运算符的普通块)并将其转换为 lambda。我尝试了明显的:
...
def on_lambda event, &callback
@callbacks[event] ||= []
@callbacks[event].push(lambda &callback)
# check if the added callback is lambda. (spoiler alert: it isn't)
puts @callbacks[event].last.lambda?
end
end
EventBus.on_lambda :baz do |x| puts x end
# I would expect the callback to be a lambda, and thus throw an ArgumentError,
# but neither of these holds.
EventBus.fire :baz
据我了解,on_lambda
需要一个块,将其转换为(通过)Proc
本地引用的块。我正在将调用with convert 的结果推回一个块。我希望这会返回一个派生自 的 lambda ,所以我的问题是:为什么数组上的元素是一个 normal 。?callback
&
lambda
callback
callback
Proc
Proc
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
更新: 在 megas 提到的提示下,
{ }
我研究了->() { }
语法(我已经看到它被称为“stab”运算符)。它从指定的块中生成一个 lambda。它可能与我想要的普通块语法和参数检查的混合一样接近。我所要做的就是调整on
方法:
def on event, callback
@callbacks[event] ||= []
@callbacks[event].push callback
end
然后像这样附加回调:
EventBus.on :bam, ->(x) do
puts x
end
但是,我仍然对原始问题感到好奇。