#ruby
#ruby
Вопрос:
Вот код:
class Something
attr_accessor :x
def initialize(x)
@x = x
end
def get_x
x
end
end
something = Something.new(5)
something.get_x # => 5
Почему интерпретатор возвращает 5, если x
это просто локальная переменная в get_x
методе? Спасибо
Ответ №1:
x
это тоже метод. attr_accessor :x
добавляет x=
и x
к вашему классу. Итак, get_x вызывает x
метод и возвращает значение для @x
. смотрите http://www.rubyist.net /~slagell/ruby/accessors.html для получения подробной информации.
Ответ №2:
attr_accessor :x
добавляет два метода для вас:
def x=(val)
@x = val
end
def x
@x
end
Таким образом, вам на самом деле не нужен get_x
getter, если вы добавили attr_accessor
метод.
UPD
Итак, вопрос в том
class Something
attr_accessor :x
def initialize(x)
@x = x
end
def set_x=(new)
x = new
end
end
Почему не будет x = new
вызываться установщик default x
: потому что установщик default x
— это метод экземпляра, поэтому вы можете вызвать его для объекта (экземпляра Something), но не в вашем классе, как вы пытаетесь.
Комментарии:
1. Но что, если у нас есть другой метод определения set_x(new_x) x = new_x end, почему интерпретатор не предполагает, что это метод x = (val)?
2. вы можете написать столько установщиков, сколько захотите.
attr_accessor
это просто «помощник», он создает для вас два метода, но вы вольны создавать столько, сколько вам нужно3. Вопрос не в том, как сделать лучше, это проблема с компилятором.
4. О, подождите, теперь я понимаю, о чем вы говорите. Если вы используете ‘self.x = new_x’, это действительно так. Это просто похоже на попытку сломать интерпретатор. Вы всегда должны четко указывать, какую переменную / метод вы хотите использовать во внутреннем коде.
5. Другой интересный пограничный случай можно увидеть, когда интерпретатор угадывает, обращаетесь ли вы к локальной переменной или вызываете метод самостоятельно. Попробуйте это:
def x; "method"; end; p x; x = 42; p x
. Перваяx
вызывает метод (поскольку локальной переменной с таким именем не существует), но вторая идентичнаяx
считывает локальную переменную. Локальные переменные маскируют методы в той же области видимости, если вы не добавляете префикс сself.
Ответ №3:
attr_accessor
Определяет метод x
(и установщик x=
), который вызывается в get_x
.
>> something.methods.grep /^x/
=> [:x, :x=]