Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为什么太阳黑子会改变搜索DSL块中的“self”?_Ruby On Rails_Ruby_Sunspot - Fatal编程技术网

Ruby on rails 为什么太阳黑子会改变搜索DSL块中的“self”?

Ruby on rails 为什么太阳黑子会改变搜索DSL块中的“self”?,ruby-on-rails,ruby,sunspot,Ruby On Rails,Ruby,Sunspot,我注意到(并在太阳黑子代码中验证)以下行为 class Foo < ActiveRecord::Base def bar search_str = "foo" Boo.search do keywords(search_str) p self.id p self end end end 注2 我在Sunspot源代码树中找到了修改正常块行为的代码。我的问题是关于这样操纵绑定的原因 注3 具体来说,我在调用块中的id方法时发

我注意到(并在太阳黑子代码中验证)以下行为

class Foo < ActiveRecord::Base
  def  bar
    search_str = "foo"
    Boo.search do
      keywords(search_str)
      p self.id
      p self
   end
 end
end
注2

我在Sunspot源代码树中找到了修改正常块行为的代码。我的问题是关于这样操纵绑定的原因

注3

具体来说,我在调用块中的
id
方法时发现了一个问题。
search
方法将块内的方法调用委托给DSL对象,如果未找到该方法,则调用将重新委托给调用上下文。在注册委托代码之前,Search方法从DSL对象中除去基本方法以外的所有方法。
id
方法未被剥离。这就是问题的根源。对于所有其他方法,委托都可以很好地工作


太阳黑子方法文档中没有记录这种行为

这不只是一个
实例评估吗?除非您谈论的是从调用上下文访问实例变量,否则这是正常的闭包行为


我假设
实例\u eval
(自身的变化)用于向块提供
关键字和其他相关方法。

好的,我知道它是如何工作的:

在util.rb的
ContextBoundDelegate
中可以找到这种魔力

  • 它创建一个空白的slate delegator对象
  • 委托人将所有方法调用转发给“接收方”。在您的示例中,“接收者”可能是包含方法
    关键字
    with
    任意
    等的对象
  • 如果在“receiver”中找不到给定的方法,则它将方法调用转发到“context”对象
  • 上下文对象是保存块绑定的对象
  • 通过执行以下操作可以找到给定块的上下文对象:
    eval('self',block.binding)
理由:

因此,所有这些的效果是,块不仅可以访问搜索对象中的方法(la
instance\u eval
),还可以访问块调用范围中的本地方法

当然,块还可以访问块的调用范围中的局部变量,但这只是正常的闭包行为

但是,块不能访问块调用范围内的实例变量


下面的代码可能很有用,因为它遵循了大致相同的思想,但简单得多,也不太复杂:

不,它不是标准的
instance\u eval
。太阳黑子库附带了一个实用程序类,方法就在该类中。在典型的块中,在创建块的过程中设置
self
的值。Sunspot DSL块中的行为不是标准的。@Kandada,您的示例代码只显示了一个普通的
实例的行为。\u eval
。您能否提供示例代码来演示
实例\u eval
未解释的行为?或者提供一个链接,指向您声称非常特殊的方法的实现@Kandada,在看了github上关于太阳黑子的代码之后,我同意这不是一个直接的
instance\u eval
。看看我的新答案。但是,您的示例并未演示此行为。:)即使您进行了更新,
栏中的行为仍然可以通过
实例\u eval
来解释。您要做的是访问
搜索
块中的本地方法。简单地证明
self
返回一个意外的对象是不相关的---这在
instance\u eval
中是正常的。更新您的示例以调用
搜索
块中的本地方法调用。使用附加注释更新问题。
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