On Mon, 14 Aug 2006, Dark A. wrote:
@country = country
end
attr_accessor(:lname, :country)
end
comp1 = Composer.new(“Beethoven”, “Germany”)
comp2 = Composer.new(“DeFalla”, “Spain”)
comp3 = Composer.new(“Debussy”, “France”)
harp:~ > cat a.rb
require ‘weakref’
class Composer
(ATTRIBUTES = %w( lname country )).each{|a| attr_accessor a}
INDEX = Hash.new{|h,k| h[k] = []}
def self.find arg
pattern =
case arg
when Hash
ATTRIBUTES.map{|a| arg[a] || arg[a.to_s] ||
arg[a.to_s.intern]}
when Array
arg
else
raise ArgumentError
end
n = pattern.size
keys = INDEX.keys.select do |key|
match = []
n.times do |i|
pat, k = pattern[i], key[i]
match <<
if pat.nil?
true
elsif pat.respond_to? 'call'
pat.call(k) ? true : false
elsif pat.respond_to? '==='
pat === k
elsif pat.respond_to? '=='
pat == k
else
false
end
end
match.all?
end
INDEX.values_at(*keys).map{|list| list.map{|weakref|
weakref.getobj}}.flatten
end
def initialize *argv
ATTRIBUTES.each{|a| send “#{ a }=”, argv.shift}
key = ATTRIBUTES.map{|a| send a}
val = WeakRef.new self
INDEX[key] << val
end
def to_hash
ATTRIBUTES.inject({}){|h,k| h.update k => send(k)}
end
def inspect
to_hash.inspect
end
def to_s
inspect
end
end
comp1 = Composer.new “Beethoven”, “Germany”
comp2 = Composer.new “DeFalla”, “Spain”
comp3 = Composer.new “Debussy”, “France”
found = Composer.find ‘lname’ => ‘Beethoven’
p found
found = Composer.find ‘lname’ => %r/^bee|^defal/io
p found
found = Composer.find :country => lambda{|c| c.upcase === ‘SPAIN’}
p found
class CaseOf < ::Array
def ===(other) flatten.compact.map{|pat| pat === other}.any? end
end
def caseof(*a, &b) CaseOf.new(*a, &b) end
found = Composer.find :lname => %r/y$/, :country => caseof(%w[ Spain
France ])
p found
harp:~ > ruby a.rb
[{“country”=>“Germany”, “lname”=>“Beethoven”}]
[{“country”=>“Germany”, “lname”=>“Beethoven”}, {“country”=>“Spain”,
“lname”=>“DeFalla”}]
[{“country”=>“Spain”, “lname”=>“DeFalla”}]
[{“country”=>“France”, “lname”=>“Debussy”}]
food for thought.
-a