【问题标题】:When using class_eval in ruby, how to access the constant in the original class?在ruby中使用class_eval时,如何访问原类中的常量?
【发布时间】:2012-10-22 21:40:40
【问题描述】:

我想使用 class_eval 扩展一个类,在尝试从原始类访问常量时,我​​收到一条错误消息:

NameError: 未初始化的常量 HIS_CONSTANT 来自 ./my_module.rb:35:in `show_his_constant' 来自 (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

但我不想使用命名空间来访问,因为它应该已经包含在内了。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    您必须使用 ruby​​ 1.8,因为您的代码似乎按照 1.9 编写的方式工作。

    在 1.8 中,问题似乎是常量绑定在定义块的上下文中(无论您开始编写 MyModule::YourModule::HisClass.class_eval 时的 self 是什么)。您可以使用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
    

    【讨论】:

    • 谢谢!我很高兴得知这是 Ruby 1.8 的限制 :) 这是一个很好的解决方法。
    【解决方案2】:

    这个怎么样

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

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 2011-11-28
      相关资源
      最近更新 更多