2012-05-05 7 views
0
BasicObject.class_eval do 
    def instance(ins) 
     eval "@#{ins}=#{ins}", binding 
    end 
end 

Это код. Я хочу, чтобы это было в следующем коде, создайте новую переменную экземпляра, bar, внутри класса Foo. Что я получаю после выполнения этого кода:Почему это возвращает ошибку?

class Foo 
    bar = 3 
end 
Foo.instance(:bar) 

является:

NameError: undefined local variable or method `bar for Foo:Class 
     from /Users/Solomon/Desktop/Ruby/instance.rb:3:in `instance' 
     from /Users/Solomon/Desktop/Ruby/instance.rb:3:in `eval' 
     from /Users/Solomon/Desktop/Ruby/instance.rb:3:in `instance' 

Почему это происходит.

+0

По той же причине, что и в предыдущем вопросе - «бар» не существует после обработки декларации класса. –

ответ

0

Пара вещей здесь .... Вы определили метод экземпляра instance для BasicObject. Затем вы вызываете этот метод экземпляра на объект Foo. Объект Foo - это класс. Вы не задали никаких переменных экземпляра для объекта Foo. Вы устанавливаете переменную экземпляра с знаком @. Все, что делает метод instance, задает переменную экземпляра @ins для себя.

, binding здесь не нужен, так как binding - это метод верхнего уровня, который возвращает привязки текущей переменной. Вам нужно сохранить только binding, если вам нужно пройти вокруг сохраненной «среды». Наличие , binding ничего не болит, но избыточно.

BasicObject.class_eval do 
    def instance(ins) 
     eval "@#{ins}= @#{ins}", binding  # @ after the '=' 
    end 
end 



class Foo 
    @bar = 3  # @ here 
end 
Foo.instance(:bar) 
puts Foo.instance_variable_get("@bar") # Shows the instance variable @bar for Foo object 
Смежные вопросы