@instance_variable 在 ruby​​ 块内不可用?

发布于 2024-10-19 19:32:29 字数 276 浏览 4 评论 0原文

使用以下代码:

def index
  @q = ""
  @q = params[:search][:q] if params[:search]
  q = @q
  @search = Sunspot.search(User) do
    keywords q
  end
  @users = @search.results
end

如果使用 @q 而不是 q,则搜索始终返回空查询 ("") 的结果。这是为什么呢? @q 变量对 do...end 块不可用吗?

With the following code:

def index
  @q = ""
  @q = params[:search][:q] if params[:search]
  q = @q
  @search = Sunspot.search(User) do
    keywords q
  end
  @users = @search.results
end

If @q is used instead of q, the search always returns results for an empty query (""). Why is this?
Is the @q variable unavailable to the do...end block?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞清仓 2024-10-26 19:32:29

这取决于块的调用方式。如果使用 yield 关键字或 Proc#call 方法调用它,那么您将能够在块中使用实例变量。如果使用 Object#instance_evalModule#class_eval 调用它,则块的上下文将被更改,并且您将无法访问实例变量。

@x = "Outside the class"

class Test
  def initialize
    @x = "Inside the class"
  end

  def a(&block)
    block.call
  end

  def b(&block)
    self.instance_eval(&block)
  end
end

Test.new.a { @x } #=> "Outside the class"
Test.new.b { @x } #=> "Inside the class"

在您的情况下,Sunspot.search 似乎正在使用 instance_eval 在不同的上下文中调用您的块,因为该块需要轻松访问该关键字 方法。

It depends on how the block is being called. If it is called using the yield keyword or the Proc#call method, then you'll be able to use your instance variables in the block. If it's called using Object#instance_eval or Module#class_eval then the context of the block will be changed and you won't be able to access your instance variables.

@x = "Outside the class"

class Test
  def initialize
    @x = "Inside the class"
  end

  def a(&block)
    block.call
  end

  def b(&block)
    self.instance_eval(&block)
  end
end

Test.new.a { @x } #=> "Outside the class"
Test.new.b { @x } #=> "Inside the class"

In your case, it looks like Sunspot.search is calling your block in a different context using instance_eval, because the block needs easy access to that keywords method.

终止放荡 2024-10-26 19:32:29

正如 Jeremy 所说,Sunspot 在新的范围内执行其搜索 DSL。

为了在 Sunspot.search 块中使用实例变量,您需要向其传递一个参数。像这样的东西应该有效(未经测试):

  @q = params[:search][:q] if params[:search]
  @search = Sunspot.search(User) do |query|
    query.keywords @q
  end
  @users = @search.results

请参阅此处以获得更好的解释:http: //groups.google.com/group/ruby-sunspot/msg/d0444189de3e2725

As Jeremy says, Sunspot executes its search DSL in a new scope.

In order to use an instance variable in the Sunspot.search block, you'll need to pass it an argument. Something like this should work (not tested):

  @q = params[:search][:q] if params[:search]
  @search = Sunspot.search(User) do |query|
    query.keywords @q
  end
  @users = @search.results

See here for a better explanation: http://groups.google.com/group/ruby-sunspot/msg/d0444189de3e2725

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文