我注意到(并在太阳黑子代码中验证)以下行为
class Foo < ActiveRecord::Base
def bar
search_str = "foo"
Boo.search do
keywords(search_str)
p self.id
p self
end
end
end
在上面的代码中,DSL 块可以访问上下文中定义的变量。但是self
内部块指向类的实例
Sunspot::DSL::Search
(而不是类的实例 Foo
)。当我尝试访问self.id
时,而不是获取
对象id
的;Foo
我得到id
一个Sunspot::DSL::Search
对象。
我认为 Sunpot 在 Util.instance_eval_or_call
方法上做了一些绑定交换/委托魔术。
我很好奇为什么 Sunspot 会这样做,以及为什么文档中没有关于这种行为的警告。
编辑:
太阳黑子搜索方法可以在这个链接找到
下面的代码将说明我的观点。在该方法foo
中,我有一个行为符合预期的块。在 methodbar
中,块没有行为。
class Order < ActiveRecord::Base
def foo
p self.class.name # prints Order
# The `self` inside the block passed to the each method
# points to an object of type Order (as expected)
# This is the normal block behavior.
[1,2,3].each do |val|
p self.class.name # prints Order
end
end
def bar
p self.class.name # prints Order
# the `self` inside the block passed to the search method
# points to an object of type Sunspot::DSL::Search.
# This is NOT the normal block behavior.
Order.search do
keywords("hello")
p self.class.name # prints Sunspot::DSL::Search
end
end
笔记2
我在 Sunspot 源代码树中找到了修改正常块行为的代码。我的问题是关于像这样操纵绑定的原因。
注3
具体来说,我在调用id
块内部的方法时发现了一个问题。该search
方法将块内的方法调用委托给 DSL 对象,如果找不到该方法,则将调用重新委托给调用上下文。在注册委托代码之前,搜索方法会从 DSL 对象中去除除基本方法之外的所有方法。该id
方法没有被剥离。这导致了问题。对于所有其他方法,委派工作正常。
Sunspot 方法文档中未记录此行为。