添加方法调用setter(序列化)

时间:2016-07-22 07:45:16

标签: ruby serialization

我有几个序列化为YAML文件的类。为了在属性更改时序列化它,我为每个属性实现了自定义setter:

def serialize
  File.open(@inipath, 'w') do |file|
    file << YAML.dump(self)
  end
end

def numbering=(value)
  @numbering = value
  serialize
end

def savepath=(value)
  @savepath = value
  serialize
end

def active=(value)
  @active = value
  serialize
end

...

这可以在没有重复的情况下完成吗?

2 个答案:

答案 0 :(得分:3)

我可能会在这里使用一些元编程秘密酱。

这是酱油:

module OptInSerialization
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def serialize_on_changes_in(*names)
      names.each do |name|
        alias_method "old_#{name}=", "#{name}="

        define_method "#{name}=" do |val|
          send("old_#{name}=", val)
          serialize
        end
      end
    end
  end
end

以下是您如何使用它:

class Foo
  include OptInSerialization

  attr_accessor :hello, :there

  serialize_on_changes_in :hello

  def serialize
    puts 'serialized'
  end
end

f = Foo.new
f.hello = '1234' # >> serialized
f.there = 'asdf'

请注意,此处序列化不是通过分配给there来触发的,因为您没有指定它。

免责声明:此MP魔法可能会高于您当前的水平,所以如果您不理解,请不要使用它。

答案 1 :(得分:0)

此处ClassName将是Model的名称,column_names将为您提供该模型的所有列。

ClassName.column_names.each do |type|
    define_method("#{type}=(value)") do
      eval"@#{type}"
      instance_variable_set("@#{type}",value )
      serialize
    end


def column_names
  ['numbering','savepath']
end