Files
news.gitea.happylizard.me/bin/gems/hashery-2.1.2/lib/hashery/property_hash.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

162 lines
3.5 KiB
Ruby

require 'hashery/crud_hash'
module Hashery
# A PropertyHash is the same as a regular Hash except it strictly limits the
# allowed keys.
#
# There are two ways to use it.
#
# 1) As an object in itself.
#
# h = PropertyHash.new(:a=>1, :b=>2)
# h[:a] #=> 1
# h[:a] = 3
# h[:a] #=> 3
#
# But if we try to set key that was not fixed, then we will get an error.
#
# h[:x] = 5 #=> ArgumentError
#
# 2) As a superclass.
#
# class MyPropertyHash < PropertyHash
# property :a, :default => 1
# property :b, :default => 2
# end
#
# h = MyPropertyHash.new
# h[:a] #=> 1
# h[:a] = 3
# h[:a] #=> 3
#
# Again, if we try to set key that was not fixed, then we will get an error.
#
# h[:x] = 5 #=> ArgumentError
#
class PropertyHash < CRUDHash
#
# Get a list of properties with default values.
#
# Returns [Hash] of properties and their default values.
#
def self.properties
@properties ||= (
parent = ancestors[1]
if parent.respond_to?(:properties)
parent.properties
else
{}
end
)
end
#
# Define a property.
#
# key - Name of property.
# opts - Property options.
# :default - Default value of property.
#
# Returns default value.
#
def self.property(key, opts={})
properties[key] = opts[:default]
end
#
# Initialize new instance of PropertyHash.
#
# properties - [Hash] Priming properties with default values, or
# if it doesn't respond to #each_pair, a default object.
# default_proc - [Proc] Procedure for default value of properties
# for properties without specific defaults.
#
def initialize(properties={}, &default_proc)
if properties.respond_to?(:each_pair)
super(&default_proc)
fixed = self.class.properties.merge(properties)
fixed.each_pair do |key, value|
store!(key, value)
end
else
super(*[properties].compact, &default_proc)
end
end
# Alias original #store method and make private.
alias :store! :store
private :store!
#
# Create a new property, on-the-fly.
#
# key - Name of property.
# opts - Property options.
# :default - Default value of property.
#
# Returns default value.
#
def property(key, opts={})
if opts[:default]
store!(key, opts[:default])
else
store!(key, retrieve(key))
end
end
#
# Store key value pair, ensuring the key is a valid property first.
#
# key - The `Object` to act as indexing key.
# value - The `Object` to associate with key.
#
# Raises ArgumentError if key is not a valid property.
#
# Returns +value+.
#
def store(key, value)
assert_key!(key)
super(key, value)
end
#
#def update(h)
# h.keys.each{ |k| assert_key!(k) }
# super(h)
#end
#
#def merge!(h)
# h.keys.each{ |k| assert_key!(k) }
# super(h)
#end
#
# Like #store but takes a two-element Array of `[key, value]`.
#
# Returns value.
#
#def <<(a)
# k,v = *a
# store(k,v)
#end
private
#
# Asserta that a key is a defined property.
#
# Raises ArgumentError if key is not a property.
#
def assert_key!(key)
unless key?(key)
raise ArgumentError, "property is not defined -- #{key.inspect}"
end
end
end
end