Har*_*tty 2 ruby ruby-on-rails sunspot
我注意到(并在太阳黑子代码中验证)以下行为
class Foo < ActiveRecord::Base
def bar
search_str = "foo"
Boo.search do
keywords(search_str)
p self.id
p self
end
end
end
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,DSL块可以访问上下文中定义的变量.但self里面块,指向的实例
Sunspot::DSL::Search类(而不是实例 Foo类.)当我试图进入self.id的不是得到的,id一个的Foo
对象; 我得到id一个Sunspot::DSL::Search对象.
我认为Sunpot在Util.instance_eval_or_call方法中做了一些绑定交换/委托魔术 .
我很好奇为什么Sunspot这样做以及为什么在文档中没有关于这种行为的警告.
编辑:
可以在此链接中找到太阳黑子搜索方法
下面的代码将说明我的观点.在方法中,foo我有一个行为符合预期的块.在该方法中bar,块不起作用.
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
Run Code Online (Sandbox Code Playgroud)
笔记2
我已经在Sunspot源代码树中找到了修改正常块行为的代码.我的问题是关于这样绑定绑定的原因.
注3
具体来说,我id在块中调用方法时发现了一个问题.该search方法将块内的方法调用委托给DSL对象,如果找不到该方法,则将调用重新委托给调用上下文.在注册委托代码之前,搜索方法从DSL对象中删除除基本方法之外的所有方法.该id方法没有被删除.这导致了这个问题.对于所有其他方法,委托工作正常.
Sunns方法文档中未记录此行为.
好的,我知道它是如何工作的:
魔术可以ContextBoundDelegate在util.rb中找到.
keywords和with和any_of等.eval('self', block.binding)理由:
因此,所有这些的效果是块不仅可以访问搜索对象中的方法(a la instance_eval),而且还可以访问块的调用范围中的本地方法.
当然,该块也可以访问块的调用范围中的局部变量,但这只是正常的闭包行为.
但是,该块不能访问块的调用范围中的实例变量.
下面的代码可能很有用,因为它遵循大致相同的想法,但更简单,更复杂:使用两个不同范围的方法?
| 归档时间: |
|
| 查看次数: |
680 次 |
| 最近记录: |