代码之家  ›  专栏  ›  技术社区  ›  knoopx

在模块内扩展时,在实例和类本身之间共享类变量

  •  3
  • knoopx  · 技术社区  · 16 年前

    我在想为什么这个代码:

    class BaseClass
    end
    
    module Extensions
      def self.included(base)
        base.extend(ClassMethods)
      end
    
      module ClassMethods
        def message(message)
          @@message = message
        end
      end
    end
    
    BaseClass.send(:include, Extensions)
    
    class ExtendedClass < BaseClass
      message "hello world!"
    
      def say_message
        puts @@message
      end
    end
    
    ExtendedClass.new.say_message
    

    输出:

    test.rb:22:in `say_message': uninitialized class variable @@message in ExtendedClass (NameError)
        from test.rb:26:in `<main>'
    

    而不是

    hello world!
    

    1 回复  |  直到 16 年前
        1
  •  2
  •   Blake Miller    16 年前

    因为执行此方法时:

    def message(message)
      @@message = message
    end
    

    @@消息引用模块ClassMethods中的类变量(不是类ExtendedClass)

    以下是一个单行更改,它可以按您期望的方式工作:

    def message(message)
      self.send(:class_variable_set, "@@message", message)
    end
    

    这有点反模式(使用'send'绕过'class\u variable\u set'是私有的事实),但我相信它回答了这个问题。

    HTH公司

    推荐文章