我在Rails上遇到了一个奇怪的问题。
我们已经设置了一个Hook
类来处理我们应用程序中的小型pub / sub机制,它就像这样
class Hook
@subscriptions = {}
class << self
def subscribe(message, &block)
@subscriptions[message] ||= []
@subscriptions[message] << block
end
def publish(message)
@subscriptions[message].each(&:call)
end
end
end
(它更加充实,但你明白了。)
问题是:
在初始值设定项中,我们得到了Hook.subscribe(:change) { ... }
但是当模型调用Hook.publish(:change)
时,没有任何反应。快速检查表明,在模型再次调用Hook
之前,defined? Hook
会返回nil
。
模型中的代码是
after_commit do
# byebug
Hook.publish(:change)
end
甚至更奇怪:在初始化器中我设置了一个全局变量来保存常量$hook = Hook
,常量确实位于模型中的$hook
变量内但与自动加载的Hook不匹配
# inside a debugger in the model
> defined? Hook
=> nil
> $hook
=> Hook
> Hook # will trigger autoloading
=> Hook
> defined? Hook
=> "constant"
> Hook == $hook
=> false
> Hook.instance_variable_get(:@subscriptions)
=> {}
> $hook.instance_variable_get(:@subscriptions)
=> { change: [<Proc:...>] }
> Hook.object_id == $hook.object_id
=> false
如果我通过调试器将其设置为常量Hook = $hook
,则所有内容都会再次正常运行 - 即使在请求中使用适当的变量也可以保持常量。
我已经到了最后。任何人都知道可能会发生什么?
答案 0 :(得分:2)
我终于找到了一个解决方案,即使我不完全理解它(我仍然有点不清楚Rails如何处理自动加载我猜 - 当我有时我还需要深入调查时间)。
Hook
类位于一个模块(OurApp::Hook
)中,为了清楚起见,我已经省略了这个模块(显然我的错误)。
我注意到OurApp.constants
丢失了Hook
以外的一些常量。
我进去了lib/our_app.rb
并对其进行了修改:
module OurApp
autoload :Hook, 'lib/our_app/hook.rb'
# ...
end
这似乎可以解决问题,而不是更多问题。
谢谢大家!