1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
module Tins
class Bijection < Hash
def self.[](*pairs)
pairs.size % 2 == 0 or
raise ArgumentError, "odd number of arguments for #{self}"
new.fill do |obj|
(pairs.size / 2).times do |i|
j = 2 * i
key = pairs[j]
value = pairs[j + 1]
obj.key?(key) and raise ArgumentError, "duplicate key #{key.inspect} for #{self}"
obj.inverted.key?(value) and raise ArgumentError, "duplicate value #{value.inspect} for #{self}"
obj[pairs[j]] = pairs[j + 1]
end
end
end
def initialize(inverted = Bijection.new(self))
@inverted = inverted
end
def fill
if empty?
yield self
freeze
end
self
end
def freeze
r = super
unless @inverted.frozen?
@inverted.freeze
end
r
end
def []=(key, value)
key?(key) and return
super
@inverted[value] = key
end
attr_reader :inverted
end
end
|