擬似ハッシュ

30分プログラム、その26。そろそろ初めてから一ヶ月になるのか。

今回は、Perlで実験的に取り入れられている疑似ハッシュ(Pseudo Hash)のRubyによる実装。
疑似ハッシュは、

{:age=>47,:eyes=>'brown',:weight=>60}

のようなハッシュを、

[{:age=>1,:eyes=>2,:weight=>3}, 47,'brown',60]

のようにハッシュと配列を組み合わせて表現する方法。

irb> phash = PHash.new(:age=>47,:eyes=>'brown',:weight=>186)
irb> phash[:age]
47

irb> phash.key? :age
true

irb> phash[:age] = 12
12
require 'forwardable'
class PHash
  include Enumerable
  extend Forwardable
  def_delegators :@key,:key?,:has_key?,:member?,:include?
  def_delegator :@value,:include?,:value?

  def initialize(hash)
    @value = hash.values
    @key = Hash[*hash.keys.zip((0..hash.size).to_a).flatten]
  end

  def each
    @key.each{|key,index|
      yield key,@value[index]
    }
  end

  def [](key)
    @value[@key[key]]
  end

  def []=(key,value)
    @key[key] = @key.size unless key? key
    @value[@key[key]] = value
  end

  def clear
    @key.clear
    @value.clear
    self
  end
end
  • これはコンパイルするとキーをインデックスに置き換えれるからいいのであって、Rubyじゃ意味ない
  • Hashクラスの全機能を実装するには時間がありません
  • 単体テストを用意するべきだった
  • Forwardableはお気に入り