class Bihash

Constants

UNIMPLEMENTED_METHODS
VERSION

Attributes

default_proc[R]

Public Class Methods

[](*args) click to toggle source
# File lib/bihash.rb, line 9
def self.[](*args)
  new_from_hash(Hash[*args])
end
new(*args, &block) click to toggle source
Calls superclass method
# File lib/bihash.rb, line 328
def initialize(*args, &block)
  raise_error_if_frozen
  if block_given? && !args.empty?
    raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
  elsif args.size > 1
    raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1)"
  end
  super()
  @forward, @reverse = {}, {}
  @default, @default_proc = args[0], block
end
try_convert(arg) click to toggle source
# File lib/bihash.rb, line 13
def self.try_convert(arg)
  h = Hash.try_convert(arg)
  h && new_from_hash(h)
end

Private Class Methods

new_from_hash(h) click to toggle source
# File lib/bihash.rb, line 308
def self.new_from_hash(h)
  bihash = new
  bihash.instance_variable_set(:@reverse, h.invert)
  bihash.instance_variable_set(:@forward, h)
  if bihash.send(:illegal_state?)
    raise ArgumentError, 'A key would be duplicated outside its own pair'
  end
  bihash
end

Public Instance Methods

<(rhs) click to toggle source
# File lib/bihash.rb, line 18
def <(rhs)
  raise_error_unless_bihash(rhs)
  merged_hash_attrs < rhs.send(:merged_hash_attrs)
end
<=(rhs) click to toggle source
# File lib/bihash.rb, line 23
def <=(rhs)
  raise_error_unless_bihash(rhs)
  merged_hash_attrs <= rhs.send(:merged_hash_attrs)
end
==(rhs) click to toggle source
# File lib/bihash.rb, line 28
def ==(rhs)
  rhs.is_a?(self.class) && merged_hash_attrs == rhs.send(:merged_hash_attrs)
end
Also aliased as: eql?
>(rhs) click to toggle source
# File lib/bihash.rb, line 32
def >(rhs)
  raise_error_unless_bihash(rhs)
  merged_hash_attrs > rhs.send(:merged_hash_attrs)
end
>=(rhs) click to toggle source
# File lib/bihash.rb, line 37
def >=(rhs)
  raise_error_unless_bihash(rhs)
  merged_hash_attrs >= rhs.send(:merged_hash_attrs)
end
[](key) click to toggle source
# File lib/bihash.rb, line 42
def [](key)
  if @forward.key?(key)
    @forward[key]
  elsif @reverse.key?(key)
    @reverse[key]
  else
    default_value(key)
  end
end
[]=(key1, key2) click to toggle source
# File lib/bihash.rb, line 52
def []=(key1, key2)
  raise_error_if_frozen
  delete(key1)
  delete(key2)
  @reverse[key2] = key1
  @forward[key1] = key2
end
Also aliased as: store
assoc(key) click to toggle source
# File lib/bihash.rb, line 60
def assoc(key)
  @forward.assoc(key) || @reverse.assoc(key)
end
clear() click to toggle source
# File lib/bihash.rb, line 64
def clear
  raise_error_if_frozen
  @forward.clear
  @reverse.clear
  self
end
compare_by_identity() click to toggle source
# File lib/bihash.rb, line 71
def compare_by_identity
  raise_error_if_frozen
  @forward.compare_by_identity
  @reverse.compare_by_identity
  self
end
default(*args) click to toggle source
# File lib/bihash.rb, line 80
def default(*args)
  case args.count
  when 0
    @default
  when 1
    default_value(args[0])
  else
    raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1)"
  end
end
default=(default) click to toggle source
# File lib/bihash.rb, line 91
def default=(default)
  raise_error_if_frozen
  @default_proc = nil
  @default = default
end
default_proc=(arg) click to toggle source
# File lib/bihash.rb, line 99
def default_proc=(arg)
  raise_error_if_frozen
  if !arg.nil?
    if !arg.is_a?(Proc)
      raise TypeError, "wrong default_proc type #{arg.class} (expected Proc)"
    end
    if arg.lambda? && arg.arity != 2
      raise TypeError, "default_proc takes two arguments (2 for #{arg.arity})"
    end
  end
  @default = nil
  @default_proc = arg
end
delete(key) { |key| ... } click to toggle source
# File lib/bihash.rb, line 113
def delete(key)
  raise_error_if_frozen
  if @forward.key?(key)
    @reverse.delete(@forward[key])
    @forward.delete(key)
  elsif @reverse.key?(key)
    @forward.delete(@reverse[key])
    @reverse.delete(key)
  else
    yield(key) if block_given?
  end
end
delete_if() { |k,v| ... } click to toggle source
# File lib/bihash.rb, line 126
def delete_if
  if block_given?
    raise_error_if_frozen
    @forward.each { |k,v| delete(k) if yield(k,v) }
    self
  else
    to_enum(:delete_if)
  end
end
dig(*keys) click to toggle source
# File lib/bihash.rb, line 136
def dig(*keys)
  (@forward.key?(keys[0]) ? @forward : @reverse).dig(*keys)
end
each(&block) click to toggle source
# File lib/bihash.rb, line 140
def each(&block)
  if block_given?
    @forward.each(&block)
    self
  else
    to_enum(:each)
  end
end
Also aliased as: each_pair
each_pair(&block)
Alias for: each
eql?(rhs)
Alias for: ==
fetch(key, *default, &block) click to toggle source
# File lib/bihash.rb, line 155
def fetch(key, *default, &block)
  (@forward.key?(key) ? @forward : @reverse).fetch(key, *default, &block)
end
fetch_values(*keys) click to toggle source
# File lib/bihash.rb, line 159
def fetch_values(*keys)
  keys.map { |key| fetch(key) }
end
filter(&block) click to toggle source
# File lib/bihash.rb, line 163
def filter(&block)
  if block_given?
    dup.tap { |d| d.select!(&block) }
  else
    to_enum(:select)
  end
end
Also aliased as: select
filter!(&block) click to toggle source
# File lib/bihash.rb, line 171
def filter!(&block)
  if block_given?
    raise_error_if_frozen
    old_size = size
    keep_if(&block)
    old_size == size ? nil : self
  else
    to_enum(:select!)
  end
end
Also aliased as: select!
has_key?(arg) click to toggle source
# File lib/bihash.rb, line 184
def has_key?(arg)
  @forward.has_key?(arg) || @reverse.has_key?(arg)
end
Also aliased as: include?, key?, member?
hash() click to toggle source
# File lib/bihash.rb, line 188
def hash
  self.class.hash ^ merged_hash_attrs.hash
end
include?(arg)
Alias for: has_key?
inspect() click to toggle source
# File lib/bihash.rb, line 194
def inspect
  "Bihash[#{@forward.to_s[1..-2]}]"
end
Also aliased as: to_s
keep_if() { |k,v| ... } click to toggle source
# File lib/bihash.rb, line 198
def keep_if
  if block_given?
    raise_error_if_frozen
    @forward.each { |k,v| delete(k) unless yield(k,v) }
    self
  else
    to_enum(:keep_if)
  end
end
key?(arg)
Alias for: has_key?
member?(arg)
Alias for: has_key?
merge(other_bh) click to toggle source
# File lib/bihash.rb, line 214
def merge(other_bh)
  dup.merge!(other_bh)
end
merge!(other_bh) click to toggle source
# File lib/bihash.rb, line 218
def merge!(other_bh)
  raise_error_if_frozen
  raise_error_unless_bihash(other_bh)
  other_bh.each { |k,v| store(k,v) }
  self
end
Also aliased as: update
rehash() click to toggle source
# File lib/bihash.rb, line 225
def rehash
  raise_error_if_frozen
  if illegal_state?
    raise 'Cannot rehash while a key is duplicated outside its own pair'
  end
  @forward.rehash
  @reverse.rehash
  self
end
reject(&block) click to toggle source
# File lib/bihash.rb, line 235
def reject(&block)
  if block_given?
    dup.tap { |d| d.reject!(&block) }
  else
    to_enum(:reject)
  end
end
reject!(&block) click to toggle source
# File lib/bihash.rb, line 243
def reject!(&block)
  if block_given?
    raise_error_if_frozen
    old_size = size
    delete_if(&block)
    old_size == size ? nil : self
  else
    to_enum(:reject!)
  end
end
replace(other_bh) click to toggle source
# File lib/bihash.rb, line 254
def replace(other_bh)
  raise_error_if_frozen
  raise_error_unless_bihash(other_bh)
  @forward.replace(other_bh.instance_variable_get(:@forward))
  @reverse.replace(other_bh.instance_variable_get(:@reverse))
  self
end
respond_to?(method, private = false) click to toggle source
Calls superclass method
# File lib/bihash/unimplemented_methods.rb, line 27
def respond_to?(method, private = false)
  UNIMPLEMENTED_METHODS.include?(method.to_s) ? false : super
end
select(&block)
Alias for: filter
select!(&block)
Alias for: filter!
shift() click to toggle source
# File lib/bihash.rb, line 266
def shift
  raise_error_if_frozen
  if empty?
    default_value(nil)
  else
    @reverse.shift
    @forward.shift
  end
end
slice(*args) click to toggle source
# File lib/bihash.rb, line 278
def slice(*args)
  self.class.new.tap do |bh|
    args.each do |arg|
      bh[arg] = self[arg] if key?(arg)
    end
  end
end
store(key1, key2)
Alias for: []=
to_h() click to toggle source
# File lib/bihash.rb, line 288
def to_h
  @forward.dup
end
Also aliased as: to_hash
to_hash()
Alias for: to_h
to_proc() click to toggle source
# File lib/bihash.rb, line 294
def to_proc
  method(:[]).to_proc
end
to_s()
Alias for: inspect
update(other_bh)
Alias for: merge!
values_at(*keys) click to toggle source
# File lib/bihash.rb, line 302
def values_at(*keys)
  keys.map { |key| self[key] }
end

Private Instance Methods

default_value(key) click to toggle source
# File lib/bihash.rb, line 319
def default_value(key)
  @default_proc ? @default_proc.call(self, key) : @default
end
illegal_state?() click to toggle source
# File lib/bihash.rb, line 323
def illegal_state?
  fw = @forward
  (fw.keys | fw.values).size + fw.select { |k,v| k == v }.size < fw.size * 2
end
initialize_copy(source) click to toggle source
Calls superclass method
# File lib/bihash.rb, line 340
def initialize_copy(source)
  super
  @forward, @reverse = @forward.dup, @reverse.dup
end
merged_hash_attrs() click to toggle source
# File lib/bihash.rb, line 345
def merged_hash_attrs
  @reverse.merge(@forward)
end
raise_error_if_frozen() click to toggle source
# File lib/bihash.rb, line 349
def raise_error_if_frozen
  raise "can't modify frozen Bihash" if frozen?
end
raise_error_unless_bihash(obj) click to toggle source
# File lib/bihash.rb, line 353
def raise_error_unless_bihash(obj)
  unless obj.is_a?(Bihash)
    raise TypeError, "wrong argument type #{obj.class} (expected Bihash)"
  end
end