Что произойдет, если я назначу переменную внутри определения класса Ruby?

class A
    a = 1
end

Что происходит в приведенном выше коде с a? Например, в Python она становится переменной класса, доступ к которой можно получить как A.a. Однако в Ruby я не знаю, как получить к нему доступ - попытки сделать это во внешней области, как a, A.a и A.new.a, приводят к ошибкам:

undefined local variable or method `a` for main (NameError)
undefined method `a` for class A (NoMethodError)
undefined method `a` for an instance of A (NoMethodError)

🤔 А знаете ли вы, что...
Ruby обладает множеством инструментов для тестирования, включая фреймворк RSpec.


50
1

Ответ:

Решено

Локальная переменная a находится в области видимости в течение всей области действия, в данном случае, пока выполняется определение класса до end из class.

Это связано с тем, что в Ruby весь код выполняется сверху вниз, включая определения классов, что позволяет вам делать такие вещи, как

class Foo
  var = :hello
  attr_accessor var
end

foo = Foo.new
foo.hello = "world"
foo.hello
# => "world"

Ruby знает переменные класса, которым предшествуют двойные символы @, например: @@var. Они действительны для класса, всех его подклассов и их объектов. Как правило, использование переменных класса не рекомендуется из-за довольно широкой области применения и часто неожиданной семантики разделения значений в подклассах.

Вместо этого вы часто будете использовать переменную экземпляра одноэлементного класса (который иногда также называют собственным классом). Это можно использовать следующим образом:

class Foo
  @foo = "foo"
  
  def self.foo
    @foo
  end

  def self.foo=(value)
    @foo
  end
end

class Bar < Foo
end

Foo.foo = "hello"
Foo.foo
# => "hello"

Bar.foo
# => nil