defineNameError при доступе к локальной переменной вне класса - PullRequest
1 голос
/ 28 октября 2009

Точная ошибка, которую я получаю: definitionNameError: undefined local variable or method 'a' for A:Class from (irb):2:in 'send' from (irb):2 from :0

Скажи, у меня есть определение класса,

class A; a = 1; end

Как можно получить значение «а» вне A?

Я пробовал:

eval 'p a', A.send(:binding)

не удалось, сказал:

NameError: undefined local variable or method `a' for A:Class
from (irb):2:in `send'
from (irb):2
from :0

Ответы [ 3 ]

1 голос
/ 19 февраля 2015

Блок (замыкание) автоматически захватывает и переносит привязки из кода, где он был создан (блок = = также является объектом):

Следовательно, локальная переменная класса может быть доступна с помощью Lambda, которая сохраняет текущее состояние локальной переменной при ее создании. Итак, поехали,

class A
  a = 100  
  # creating lambda at class level as 'a' is a local variable of class A
  @l = lambda { a } 
  class << self
    attr_reader :l
  end
end
puts A.l.call # => 1
0 голосов
/ 28 октября 2009

С этим точным определением есть способ:

secret_val = class A; a = 1; end
puts a

В противном случае, когда контекст определения класса исчезнет, ​​локальная переменная исчезнет.

Wait. В исходном вопросе викторины, на который вы ссылались в комментариях, это переменные экземпляра, а не локальные. Это торт. Просто используйте instance_variable_get("@a") для класса и экземпляра соответственно.

0 голосов
/ 28 октября 2009

Я так не думаю (не прибегая к проверке источника). Привязка в конечном счете связана с некоторой лексической областью: как получить к ней доступ из другого, если она не была сохранена? Пример ниже читов, конечно.

b = class A
  x = 20
  binding
end

eval "p x", b

Это также может зависеть от реализации (например, на 1.8.7, но не на 1.9). Я перепробовал все комбинации привязок и / или local_variables, которые я могу придумать и до сих пор не люблю. Конечно, я мог бы просто сделать это неправильно . Было бы неплохо увидеть решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...