Переменная области видимости Ruby

#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=]