我想使用class_eval扩展一个类,并且在尝试从原始类访问常量时,我得到一个错误说:
NameError:未初始化的常量HIS_CONSTANT来自./my_module.rb:35:来自(irb)的“show_his_constant”: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但我不想使用命名空间来访问,因为它应该已经包含在内。
I want to extend a class using class_eval, and while trying to access the constant from the original class, I got an error saying:
NameError: uninitialized constant HIS_CONSTANT from ./my_module.rb:35:in `show_his_constant' from (irb):4
I tested with a sample program, and can't make it work. Can someone pls check and see why this is not working? Thanks!
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 endBTW, I know this way can work:
MyModule::YourModule::HisClass.class_eval do def show_his_constant puts MyModule::YourModule::HisModule::HIS_CONSTANT end endBut I don't want to use namespace to access, since it should already be included.
最满意答案
你必须使用ruby 1.8,因为你的代码看起来像1.9中所写的那样工作。
在1.8中,问题似乎是常量被定义在块的定义的上下文中(当你开始编写MyModule::YourModule::HisClass.class_eval时,无论是什么样的self )。 您可以通过使用Module.const_get延迟常量绑定,直到self成为MyModule::YourModule::HisClass的Module.const_get 。
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_CONSTANTYou must be using ruby 1.8 as your code appears to work as written in 1.9.
In 1.8 the problem seems to be that the constant is bound in the context of where the block is defined (whatever self was when you started to write MyModule::YourModule::HisClass.class_eval). You can delay the constant binding until self has become an instance of MyModule::YourModule::HisClass by using Module.const_get.
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更多推荐
发布评论