Files
news.gitea.happylizard.me/bin/gems/hashery-2.1.2/lib/hashery/association.rb
T
pizza2d1 4cee170d66
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s
Add bin and edit workflow
2026-09-16 13:11:16 -06:00

223 lines
4.6 KiB
Ruby

module Hashery
# TODO: Should associations be singleton?
#
# TODO: Is it really wise to keep a table of all associations?
# Association is a general binary association that allows one
# object to be associated with another. It has a variety of uses,
# such as linked-lists, simple ordered maps and mixed collections,
# among them.
#
# NOTE: This class is still fairly experimental. And it is not
# loaded along with the other Hashery libraries when using
# `require 'hashery'`. It must be required independently.
#
# Associations can be used to draw simple relationships.
#
# :Apple >> :Fruit
# :Apple >> :Red
#
# :Apple.associations #=> [ :Fruit, :Red ]
#
# It can also be used for simple lists of ordered pairs.
#
# c = [ :a >> 1, :b >> 2 ]
# c.each { |k,v| puts "#{k} associated with #{v} }
#
# produces
#
# a associated with 1
# b associated with 2
#
# The method :>> is used to construct the association.
# It is a rarely used method so it is generally available.
# But you can't use it for any of the following classes
# becuase they use #>> for other things.
#
# Bignum
# Fixnum
# Date
# IPAddr
# Process::Status
#
class Association
include Comparable
class << self
#
# Store association references.
#
# Returns `Hash` of all associaitons.
#
def reference
@reference ||= Hash.new{ |h,k,v| h[k]=[] }
end
#
# Shortcut for #new.
#
# index - The "index key" of the association.
# value - The "value" of the association.
#
# Returns `Association`.
#
def [](index, value)
new(index, value)
end
#def new(index, value)
# lookup[[index, value]] ||= new(index, value)
#end
#def lookup
# @lookup ||= {}
#end
end
#
# The "index key" of the association.
#
attr_accessor :index
#
# The "value" of the association.
#
attr_accessor :value
#
# Initialize new Association.
#
# index - The "index key" of the association.
# value - The "value" of the association.
#
def initialize(index, value=nil)
@index = index
@value = value
unless index.associations.include?(value)
index.associations << value
end
end
#
# Compare the values of two associations.
#
# TODO: Comparions with non-associations?
#
# assoc - The other `Association`.
#
# Returns [Integer] `1`, `0`, or `-1`.
#
def <=>(assoc)
return -1 if self.value < assoc.value
return 1 if self.value > assoc.value
return 0 if self.value == assoc.value
end
#
# Invert association, making the index the value and vice-versa.
#
# Returns [Array] with two-elements reversed.
#
def invert!
temp = @index
@index = @value
@value = temp
end
#
# Produce a string representation.
#
# Returns [String].
#
def to_s
return "#{index} >> #{value}"
end
#
# Produce a literal code string for creating an association.
#
# Returns [String].
#
def inspect
"#{index.inspect} >> #{value.inspect}"
end
#
# Convert to two-element associative array.
#
# Returns [Array] Two-element Array of index and value pair.
#
def to_ary
[index, value]
end
#
# Object extensions.
#
module Kernel
#
# Define an association for +self+.
#
# to - The value of the association.
#
# Returns [Association].
#
def >>(to)
Association.new(self, to)
end
#
# List of associations for this object.
#
# Returns an `Array` of `Associations`.
#
def associations
Association.reference[self]
end
end
end
end
class Object #:nodoc:
include Hashery::Association::Kernel
end
#--
# Setup the >> method in classes that use it already.
#
# This is a bad idea b/c it can cause backward compability issues.
#
# class Bignum
# alias_method( :rshift, :>>) if method_defined?(:>>)
# remove_method :>>
# end
#
# class Fixnum
# alias_method( :rshift, :>>) if method_defined?(:>>)
# remove_method :>>
# end
#
# class Date
# alias_method( :months_later, :>>) if method_defined?(:>>)
# remove_method :>>
# end
#
# class IPAddr
# alias_method( :rshift, :>>) if method_defined?(:>>)
# remove_method :>>
# end
#
# class Process::Status
# alias_method( :rshift, :>>) if method_defined?(:>>)
# remove_method :>>
# end
#++
# Copyright (c) 2005 Rubyworks, Thomas Sawyer