There is a very clear practical difference in how lexical and instance variables work:
class Thing
def initialize
@ivar = "Hello World"
end
def foo
@ivar
end
end
> Thing.new.foo
=> "Hello World"
Since instance variables are attached to the instance they can be shared among methods of an object without passing by value as typically used by callbacks:
class API::V1::ThingsController < ::ApiController
before_action :set_thing, except: [:create, :index]
def show
respond_with @thing
end
# ...
private
def set_thing
@thing = Thing.find(params[:id])
end
end
This can be immensely useful when considering the convention over configuration focus of rails. Controller IVARs are also available in the view through the view context.
Lexical variables on the other hand only exist in the lexical scope where the are defined (the method, block, proc or lambda):
class Thing
def initialize
lex = "Hello World"
end
def foo
lex
end
end
> Thing.new.foo
NameError: undefined local variable or method `lex' for #<Thing:0x007f87068b5968>
They are preferable when you need a short lived variable with a local scope. Rails also has locals which is actually a hash where you can stuff things when rendering which should not be conflated with the Ruby concept of lexical variables. Rails uses method_missing in the view context to proxy to the locals hash.
The performance difference is most likely extremely negible as both are just variables that are bound to a scope - either the object or a method/block. The lexical variable will recycled by the GC when the scope is closed (the method finishes) though while an instance variable will persist with the object. This is rarely an issue though.
some_file.json.jbuilderfiles.