繁体   English   中英

在类定义期间添加实例方法

[英]Adding instance methods during class definition

我目前正在开发我的第一个宝石,并在元编程方面取得了初步经验。

因此,我希望获得一些有关如何在类定义期间正确定义实例方法的反馈。

具体来说,我创建了此模块,您应该将其extend到ActiveRecord模型中,如下所示:

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

它似乎有效,但我有一些担忧:

  1. class_eval是在此处使用的正确方法吗?
  2. define_method是在此处使用的正确方法吗?
  3. 选项哈希将传递到类方法中,并在实例方法主体内使用。 这样安全吗? 有记忆问题吗?

如果您可以使用ActiveSupport :: Concern ,那将是一种标准化的方式。

如果没有,您总是可以做类似的事情。

我不会担心内存问题。 一般来说,哈希很小。 我担心的是,如果传递这些选项的调用者不知道您会坚持使用它们。 例如:

options = { :foo => 'var', :bar => 'example' }

unite :name_1, :unit_a, options

options.delete(:example)

unite :name_2, :unit_b, options

在这种情况下,对options哈希的修改会无意中影响到两者。 解决此问题的办法是dupclone传入的选项,或更好,挑出你想要的值,如果接收到未知的争论引发异常。 options哈希不应该视为unite方法的属性。

如果呼叫者传入一组frozen的选项,您还将遇到麻烦。 您的merge!电话merge! 会产生异常。 通常,除非将方法专门用于执行此类功能,否则将操作传递给方法的参数视为无效形式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM