[英]Adding instance methods during class definition
I'm currently working on my first gem and making my first experiences in meta programming. 我目前正在开发我的第一个宝石,并在元编程方面取得了初步经验。
Therefore, I would like some feedback on how to correctly define an instance method during a class definition. 因此,我希望获得一些有关如何在类定义期间正确定义实例方法的反馈。
Specifically, I created this module that you are supposed to extend
in your ActiveRecord models like this: 具体来说,我创建了此模块,您应该将其
extend
到ActiveRecord模型中,如下所示:
class Duck < ActiveRecord::Base
extend UnitedAttributes::Model
attr_accessible :name, :weight
unite :weight, :kilogram
end
Here is the source for the UnitedAttribues::Model
module. 这是
UnitedAttribues::Model
模块的源代码。 https://github.com/nielsbuus/united_attributes/blob/master/lib/united_attributes/model.rb https://github.com/nielsbuus/united_attributes/blob/master/lib/united_attributes/model.rb
And here is a shortened version without superfluous code: 这是没有多余代码的简化版本:
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
It appears to work, but I have some concerns: 它似乎有效,但我有一些担忧:
class_eval
the correct method to use here? class_eval
是在此处使用的正确方法吗? define_method
the correct method to use here? define_method
是在此处使用的正确方法吗? If you can use ActiveSupport::Concern , that would be a standardized way of doing this. 如果您可以使用ActiveSupport :: Concern ,那将是一种标准化的方式。
If not, you could always do something similar. 如果没有,您总是可以做类似的事情。
I wouldn't be worried about memory concerns. 我不会担心内存问题。 A hash is small, generally speaking.
一般来说,哈希很小。 What I would be worried about is if the caller that passes in these options is unaware you'll be persisting them.
我担心的是,如果传递这些选项的调用者不知道您会坚持使用它们。 For example:
例如:
options = { :foo => 'var', :bar => 'example' }
unite :name_1, :unit_a, options
options.delete(:example)
unite :name_2, :unit_b, options
In this case, the modification of the options
hash would impact both inadvertently. 在这种情况下,对
options
哈希的修改会无意中影响到两者。 One way around this is to dup
or clone
the incoming options, or better, to pick out the values you want and raise an exception if an unknown argument is received. 解决此问题的办法是
dup
或clone
传入的选项,或更好,挑出你想要的值,如果接收到未知的争论引发异常。 The options
hash should not be considered the property of the unite
method. options
哈希不应该视为unite
方法的属性。
You'll also run in to trouble if a caller passes in a frozen
set of options. 如果呼叫者传入一组
frozen
的选项,您还将遇到麻烦。 Your call to merge!
您的
merge!
电话merge!
will produce an exception. 会产生异常。 In general, manipulating an argument passed in to a method is considered bad form unless the method is specifically intended to perform that kind of function.
通常,除非将方法专门用于执行此类功能,否则将操作传递给方法的参数视为无效形式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.