Это распространенная ошибка, сделанная Java-кодонами, приходящими на Ruby, а также один из больших концептуальных прыжков, с которыми мне пришлось столкнуться. Сначала это кажется странным, но на самом деле это один из самых крутых аспектов Ruby - весь исполняемый код, включая определения классов.
Итак, переменные экземпляра должны быть объявлены внутри методов. Это связано с тем, как оценивается «я». «Я» - текущий объект. Интерпретатор будет искать вызовы методов и ссылки на переменные сначала в «я»:
class Fish
@var = "foo" # here 'self' == Fish, the constant which contains the class object
def foo
# do foo
end
end
fish = Fish.new
fish.foo # here 'self' == fish, an instance of Fish
В определении класса «я» устанавливаются, чтобы быть объектом класса определяется, таким образом, любые ссылки внутри определения класса будут относиться к этот объект класса, в данном случае Fish.
Однако, когда метод вызывается в экземпляре Fish, self устанавливается как получатель вызова, конкретный экземпляр Fish. Таким образом, вне определения метода self является объектом класса. Внутри метода self является экземпляром приемника. Вот почему @var вне определения метода больше похоже на статическую переменную в Java, а @var внутри определения метода - это переменная экземпляра.
не должен» t, который будет @@ var в первом блоке кода? – Jean
Я читаю «Хорошо обоснованный рубист» (http://manning.com/black2/) Дэвида Блэка. Он отлично справляется с объяснением всех нюансов в этой области. –
Jean: Нет. Если бы я использовал '@@ var', то подклассы переопределяли родительские классы. См. Ссылку hobodave. В частности, как «2» переоценивается в этом примере. –