模块与包装器在哈希扩展中访问键值作为属性



我是Ruby新手,我对哈希值不能作为对象(myHash.key)访问感到有点失望,正如许多其他问题(例如:如何将哈希键用作类的方法?)我不喜欢openstruct解决方案,因为它不是递归的,而且我不想修改Hash类。

因此,我开发了以下解决方案。首先定义以下模块:

module NiceHash
  def method_missing(name, *args, &blk)
    if args.empty? && blk.nil? && self.has_key?(name.to_s)
      result=self[name.to_s]
      if result.is_a? Hash
        result.extend(Nice_Hash)
      end
      return result
   else
     super
   end
  end
  def respond_to?(sym, include_private = false)
    super(sym, include_private) || (self.has_key?(sym.to_s))
  end
end

然后和

一起使用
a={"a"=>"a"}
a.extend(NiceHash)
a.a

解决方案有效。

我的问题是:这也可以用包装器类来完成。哪个更好?

回答您关于解决方案中隐藏问题的问题,主要有两个问题。

  1. 正如其他人在评论中提到的,当键不是有效的ruby方法名时,它将会中断。
  2. 你的解决方案是基于method_missing,就像OpenStruct一样。因此,它也有同样的缺点。如OpenStruct文档中所述:

OpenStruct使用Ruby的方法查找结构来查找和为属性定义必要的方法。这就完成了通过方法method_missing和define_method.

这应该是一个考虑,如果有一个关注所创建对象的性能,因为有更多与使用散列相比,在设置这些属性方面的开销更大

最新更新