我目前正在研究我的第一个宝石并开始我的元编程经验。
因此,我想要一些关于如何在类定义中正确定义实例方法的反馈。
具体来说,我创建了这个模块,您应该在ActiveRecord模型中extend
,如下所示:
class Duck < ActiveRecord::Base
extend UnitedAttributes::Model
attr_accessible :name, :weight
unite :weight, :kilogram
end
以下是UnitedAttribues::Model
模块的来源。 https://github.com/nielsbuus/united_attributes/blob/master/lib/united_attributes/model.rb
这是一个缩短版本,没有多余的代码:
module UnitedAttributes
module Model
def unite(accessor, unit, options = {})
class_eval do
define_method "united_#{accessor}" do
Attribute.new(self.send(accessor), options)
end
end
end
end
end
它似乎有用,但我有一些顾虑:
class_eval
这里使用的是正确的方法吗?define_method
这里使用的是正确的方法吗?答案 0 :(得分:0)
如果你可以使用ActiveSupport::Concern,那将是一种标准化的方式。
如果没有,你总是可以做类似的事情。
我不担心内存问题。一般来说,散列很小。我担心的是,如果通过这些选项的来电者不知道你会坚持他们。例如:
options = { :foo => 'var', :bar => 'example' }
unite :name_1, :unit_a, options
options.delete(:example)
unite :name_2, :unit_b, options
在这种情况下,options
哈希的修改会无意中影响。解决此问题的一种方法是向dup
或clone
传入选项,或者更好,选择所需的值,并在收到未知参数时引发异常。 options
哈希不应被视为unite
方法的属性。
如果来电者传递了frozen
个选项,您也会遇到麻烦。您拨打merge!
会产生异常。通常,操纵传入方法的参数被认为是不好的形式,除非该方法专门用于执行这种功能。