2012-10-22 13 views
4

我想用class_eval,擴展類,並嘗試從原來的類訪問常數,我得到了一個錯誤說:在ruby中使用class_eval時,如何訪問原始類中的常量?

NameError:未初始化不斷HIS_CONSTANT 從./my_module.rb:35:in` show_his_constant' from(irb):4

我測試了一個示例程序,但無法使其工作。有人可以檢查,看看爲什麼這不起作用嗎?謝謝!

module MyModule 
    puts "start my module" 
    def mytest 
    puts "mytest" 
    end 

    module YourModule 
    def yourtest 
     puts "yourtest" 
    end 
    end 
end 

module MyModule 
    module YourModule 
    module HisModule 
     HIS_CONSTANT = 'THIS_IS_A_CONSTANT' 
    end 
    end 
end 

module MyModule 
    module YourModule 
    class HisClass 
     include HisModule 
     def show_constant 
     puts HIS_CONSTANT 
     end 
    end 
    end 
end 

MyModule::YourModule::HisClass.class_eval do 
    def show_his_constant 
    puts HIS_CONSTANT 
    end 
end 

順便說一句,我知道這樣可以工作:

MyModule::YourModule::HisClass.class_eval do 
    def show_his_constant 
    puts MyModule::YourModule::HisModule::HIS_CONSTANT 
    end 
end 

但我不希望使用的命名空間來訪問,因爲它應該已經被包括在內。

回答

4

爲您的代碼出現寫在1.9到工作,你必須使用紅寶石1.8。

在1.8中,問題似乎是常數在塊定義的上下文中被綁定(無論self是什麼時候開始寫入MyModule::YourModule::HisClass.class_eval)。您可以通過使用Module.const_get來延遲恆定綁定,直到self成爲MyModule::YourModule::HisClass的實例。

MyModule::YourModule::HisClass.class_eval do 
    def show_his_constant 
    puts self.class.const_get(:HIS_CONSTANT) 
    end 
end 

irb 1.8.7> MyModule::YourModule::HisClass.new.show_his_constant 
THIS_IS_A_CONSTANT 
+0

謝謝!我很高興知道這是Ruby 1.8的限制:)這是一個很好的解決方法。 – Jimmy

0

這個怎麼樣

MyModule::YourModule::HisClass.class_eval do 
    def show_his_constant 
    puts self::class::HIS_CONSTANT 
    end 
end 
相關問題