mbajur
mbajur

Reputation: 4484

How to access instance variable from a block

I have a pretty lame question regarding ruby. I have a following code:

@node          = Node.find(params[:id])
@similar_nodes = Tire.search 'nodes', load: true do
  query do
    fuzzy_like_this @node.title
  end
end

The problem is, that, for some reason, i can't access @node variable in fuzzy_like_this line. It returns nil even if Node has been found and i can access it in the second line. Can you please give me any advice why is that happening and what can i do to understand that behaviour better? I don't even know how to search for that.


Edit: Sorry for the typo in the title, ofcourse it should not be a "global" variable but instance variable.

Upvotes: 0

Views: 348

Answers (2)

Renato Zannon
Renato Zannon

Reputation: 30001

Variables starting with '@' aren't global; they are instance variables. This means that they belong to a particular object, being (mostly) inaccessible from others.

What seems to be happening is that the search method is changing the context of execution (probably via instance_eval/instance_exec), which means that, inside the block, your self isn't the same, and you won't have access to the same instance variables.

A simple workaround is to use a local variable instead:

node           = Node.find(params[:id])
@similar_nodes = Tire.search 'nodes', load: true do
  query do
    fuzzy_like_this node.title
  end
end

Then, if you really need node to be an instance variable, you can assign it later:

@node = node

Upvotes: 1

crazymykl
crazymykl

Reputation: 544

Node is an instance variable, not a global. Since the block may be (in this case, is) executed in the context of another object, your ivars aren't there. Assigning the ivar value to a local name should work, as locals are lexically scoped.

tl;dr: node = @node, use local node within block.

Upvotes: 2

Related Questions