子类化核心Ruby类,如Hash

我需要一个类似Hash的类,但不一定需要所有的Hash方法.我已经读过像Hash那样继承核心类并不是一个好主意.无论这是否属实,做这种事情的最佳做法是什么?
# (a) subclass Hash,add new methods and instance variables
class Book < Hash
   def reindex
     @index = .....
   end
end

# (b) create a new class from scratch,containing a hash,#    and define needed methods for the contained hash
class Book
  def initialize(hash)
    @data = hash
  end 
  def []=(k,v)
    @data[k] = v
  end
  # etc....
  def reindex
    @index = ....
  end

# (c) like (b) but using method_missing

# (d) like (b) but using delegation

我意识到Ruby有多种方法可以完成给定的任务,但在相对简单的情况下,是否有任何一般规则可以解决上述哪种方法

解决方法

如果我绝对不希望类似Hash的对象具有某些哈希方法,那么我会将该对象包装在我自己的类中,并且只显示我想要的方法(您的选项b).

如果我希望它通过一些添加的行为来维护其真正的哈希行为,我会在模块中将该行为添加到哈希对象本身,而不是修改核心哈希类:

module SpecialHash
  def reindex
    # method def
  end
end

my_hash = {}
my_hash.extend(SpecialHash)
my_hash.reindex #Now is defined on my hash

最常见的是,其中一个选项可以帮助我.

一般来说,我倾向于使用模块来扩展类行为而不是类继承,因为我认为它是一种更清晰,更轻量级的方法.创建一个新类总让我感觉我正在为我的域模型添加一个新的“东西”.这很好,正是你想要在无数场景中做的事情,但Ruby的mixin功能为你提供了一个非常好的选择,而你实际上并不需要那么远.

我要处理创建类的主要时间是在对象中是否存在我想要跟踪的其他状态.如果我的添加不是扩展对象的状态,而只是扩展它的行为,那么我几乎总是首先使用模块将该行为混合到该类的现有实例中.

对这类问题的另一个答案也提出了一些值得记住的其他要点:
ruby inheritance vs mixins

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...