Ruby: переменные экземпляра и локальные переменные

Я изучаю Ruby прямо сейчас, и я смущен тем, почему я могу ссылаться на переменную экземпляра без @sigil, что также сделает ее локальной. Разумеется, следующий код не должен работать так:

class Test
  attr_accessor :variable
  def something
    variable
  end
  def something2
    @variable
  end
  def something3
    self.variable
  end
end

y = Test.new
y.variable = 10
puts y.something  # => 10
puts y.something2 # => 10
puts y.something3 # => 10

Я бы ожидал, что y.something вернет нуль. Почему локальные переменные и переменные экземпляра указывают на одно и то же местоположение? Я бы ожидал, что @variable и variable будут двумя дискретными переменными.

Ответ 1

В опубликованном вами коде variable есть не локальная переменная. Это метод метода для метода экземпляра с именем variable, который был определен:

attr_accessor :variable

Это сокращение для следующих определений методов:

def variable
  @variable
end

def variable=(value)
  @variable = value
end

Обратите внимание, что Ruby не требует скобок () для вызова метода, поэтому различие между локальной переменной и методом не всегда легко.

Сравните ваш код с:

class Test
  attr_accessor :foo

  def example1
    foo = nil  # 'foo' is now a local variable
    foo
  end

  def example2
    foo        # 'foo' is a method call
  end
end

x = Test.new
x.foo = 10
x.example1  # => nil
x.example2  # => 10