【问题标题】:Ruby: How to Work With Class Vars in a ModuleRuby:如何在模块中使用类变量
【发布时间】:2012-07-30 23:36:10
【问题描述】:

说到这个,我总是脑抽筋。我正在创建一个模块来混合到类似模型的类中,但它需要为每个类保留一份可序列化属性的副本。所以这是代码(不起作用)。

module Checkin
  module Model
    def self.included(base)
      base.extend(ClassMethods)
    end

    @@serialiable_attrs = []   <== really not the right place
    module ClassMethods
      def serializable(*attrs)
        attrs.each{|attr| @@serializable_attrs << attr} # Is this @@ or just @?
      end
    end

    def serialize!
      @@serializable_attrs.each{|a| do_something_with(a)} # <== Will this work?
    end
  end
end

class Person  
  include Checkin::Model
  serializable :first_name, :original_name, :last_name, :checked_in, :people_attending
  # etc., etc.
end

我在争论的是两件事:

  1. 如何定义我的混入,使类变量神奇地出现;和
  2. 如何在我的ClassMethods 模块和模块的实例方法部分(因为没有更好的术语)访问该变量。

请注意,我选择了混合技术而不是继承,因为我将拥有ValidatablePersistableSerializable 等等。此外,我知道有各种可用的验证和持久层,它们经过了良好的测试和大量使用。这是一种不同的野兽,我真的应该知道在睡梦中该由谁来做,对吧?

任何可以帮助我理解如何执行此操作或建议解决此问题的不同方向的 Ruby 向导,感谢您的帮助!

【问题讨论】:

    标签: ruby metaprogramming


    【解决方案1】:

    尝试删除类变量,并将其添加到模块ClassMethod

    def self.extended(klass)
      klass.instance_variable_set("@serializable_attrs", [])
    end
    

    serializable 中将双@ 更改为单。并将serialize! 更改为:

    self.class.instance_variable_get("@serializable_attrs").each{|a| do_something_with(a)}
    

    【讨论】:

    • 谢谢!当我想,“这太丑陋了”时,我走了一半。我很高兴看到这只是我的想象,而且这是对的。
    • @SteveRoss:很高兴我能帮上忙。只需在脑海中计算出self 的值即可。这是 Ruby 元编程的关键。 Ruby 从不施展任何黑魔法,记住这一点。
    猜你喜欢
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2012-01-06
    • 2011-08-07
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多