Что произойдет, если я назначу переменную внутри определения класса 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)

Это локальная переменная в контексте тела класса, действительная во время оценки этого тела. После этого вы не сможете получить к нему доступ.

Stefan 20.08.2024 13:01

@ Стефан - Спасибо, это имеет смысл. Похоже, я могу получить доступ к a, используя что-то вроде class A; a = 1; print(a); end. Вот и все: a недоступен внутри каких-либо методов, определенных внутри A, поскольку методы не являются замыканиями.

user200783 20.08.2024 13:09

Если вы не используете define_method, см. stackoverflow.com/a/30258403/477037

Stefan 20.08.2024 14:35
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

Другие вопросы по теме