Существует очень четкое практическое различие в том, как работают лексические переменные и переменные экземпляра:
class Thing
def initialize
@ivar = "Hello World"
end
def foo
@ivar
end
end
> Thing.new.foo
=> "Hello World"
Поскольку переменные экземпляра присоединены к экземпляру, они могут совместно использоваться методами объекта без передачи по значению, как обычноиспользуется обратными вызовами:
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
Это может быть очень полезно при рассмотрении соглашения о конфигурации фокуса рельсов.Контроллеры IVAR также доступны в представлении через контекст представления.
Лексические переменные, с другой стороны, существуют только в лексической области, где определены (метод, блок, процесс или лямбда):
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>
Они предпочтительнее, когда вам нужен короткийживая переменная с локальной областью видимости.В Rails также есть locals
, который на самом деле является хешем, в который можно добавлять вещи при рендеринге, что не должно быть связано с концепцией лексических переменных в Ruby.Rails использует method_missing
в контексте представления для передачи хешу локальных данных.
Разница в производительности, скорее всего, крайне незначительна, поскольку обе являются просто переменными, которые связаны с областью действия - либо объектом, либо методом / блоком,Лексическая переменная будет переработана GC, когда область будет закрыта (метод завершится), хотя переменная экземпляра будет сохранена с объектом.Это редко проблема, хотя.