Ruby Enumerable with underlying Hash

时间:2014-11-16 20:43:57

标签: ruby enumerable

我有一个使用EnumerableForwardable mixins的课程。问题是即使#each已经实施(或委托),#member?(也随Enumerable提供)也无法正常工作。

require "forwardable"
class RestrictedHash
  include Enumerable
  extend Forwardable

  def_delegators :@hash, :[], :[]=, :each

  def initialize
    @hash = {}
  end
end

r_h = RestrictedHash.new
r_h[:a] = []
r_h.member?(:a)       #=> false
r_h.member?(:a, [])   #=> Wrong number of arguments (2 for 1)
r_h.member?([:a, []]) #=> true

h = {}
h[:a] = []
h.member?(:a)         #=> true
h.member?([:a, []])   #=> false

为什么我在行为上有这种差异的任何想法?

1 个答案:

答案 0 :(得分:1)

原因是each上的Hash方法产生了键和值对,因此对于您的示例@hash

irb(main):001:0> h = {}
=> {}
irb(main):002:0> h[:a] = []
=> []
irb(main):003:0> h.each { |i| puts i.inspect }
[:a, []]

这意味着当member?Enumerable的实施使用each检查指定的值是否为成员时,它将成功找到([:a, []]但不会找到密钥{ {1}}本身。

:a班级本身Hashimplemented to call rb_hash_has_key