2013-05-06 2 views
3

У меня есть класс рубина, как это:переменного класс рубина в метаклассе

class C 
    @@v = 1 

    class << self 
    p @@v # everything goes well here 
    end 
end 

class << C 
    # here I get an exception 
    # `singletonclass': uninitialized class variable @@v in Object (NameError) 
    # from a.rb:5:in `<main>' 

    p @@v 
end 

Моего вопрос заключается в следующем: исключение сказало: «неинициализированная переменная класса @@ v в Object (NameError)», но почему рубиновый Lookups переменного класса в Object (main)?

Кажется, что Ruby всегда ищет переменные класса metaclass вне его.

+0

Когда вы сделали «класс << с вы действительно используете самость, которая является основным , который находится под объектом, правильно? – vgoff

+0

@vgoff Что означало: ** Когда вы делали «класс << c, вы действительно используете self ** – user2016971

+0

В вашем втором классе << self definition, область main, снова. Однако в этой области нет переменной класса @@ v. Так вы не ожидаете получить эту ошибку? – vgoff

ответ

0

Я считаю, что это проблема Ruby. Верхний и нижний коды имеют одинаковые «я» и «класс» и должны давать одинаковые результаты. Сообщите нам о проблеме в http://bugs.ruby-lang.org/issues/

3

Вы определили переменную класса @@v для класса C. Мы не должны быть удивлены, что это:

class << C 
    p @@v 
end 

вызывает исключение, потому что здесь мы имеем дело с singleton class из C, для которого мы не определили класс переменной @@v.

реальный вопрос есть, Почему он работает, когда вы это делаете?

class C 
    @@v = 1 

    class << self 
    p @@v 
    end 
end 

Ответ, как представляется, что для вашего удобства, когда вы получаете доступ к одноплодной класса внутри этого класса, рубин прозрачно предоставляет доступ к переменным класса этого класса.

Обратите внимание, что это работает последовательно при определении методов, а также, используется ли class << self; def method_name синтаксис или синтаксис def self.method_name:

# assuming @@v in C is 1 
class C 
    def self.print_v_from_inside 
    p @@v 
    end 
end 

def C.print_v_from_outside 
    p @@v 
end 

C.print_v_from_inside 
# => 1 

C.print_v_from_outside 
# => NameError: uninitialized class variable @@v in Object 
Смежные вопросы