2009-10-28 3 views
1

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

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

class A; a = 1; end

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

Я пробовал:

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 
+0

Могу ли я спросить * почему * вам нужно копать непосредственно в класс, чтобы получить одну локальную переменную? Какая большая картина? – Telemachus

+0

к Телемаху, На самом деле, это не я хочу копаться в класс, это испытание от http://ruby-metaprogramming.heroku.com/html/Exercise_1.html – leomayleomay

ответ

0

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

b = class A 
    x = 20 
    binding 
end 

eval "p x", b 

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

+0

хороших, точка здесь является доступ к локальной переменной без возврата привязки – leomayleomay

0

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

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

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

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

+0

к Chuck, serect_val = class A; a = 1; end puts secret_val напечатает 1 на экране, это правильно, но как вы могли получить значение «a», если это не последнее выражение в определении класса? – leomayleomay

+0

@Chuck есть 'a' в дополнение к @a и @@ a :( – 2009-10-28 07:11:23

1

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

Следовательно, локальная переменная класса можно получить с помощью 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 
Смежные вопросы