Phrogz wrote:
I had hoped that the following would work, but no luck:
[snip]
The reason that what I posted didn’t work is because I mispelled ‘eql?’
as ‘eq?’. Oops. Following is code that does actually work:
class Object
def equiv; self; end
end
class Equiv
def self.[]( data, equiv )
self.new( data, equiv )
end
attr_accessor :data, :equiv
def initialize( data, equiv )
@data, @equiv = data, equiv
end
def <=>( o2 ); @equiv <=> o2.equiv end
def == ( o2 ); @equiv == o2.equiv end
def ===( o2 ); @equiv === o2.equiv end
def eql?( o2 ); @equiv.eql?( o2.equiv ) end
def hash; @equiv.hash end
end
possible = [
Equiv[ 1001, ‘a’ ],
Equiv[ 1002, ‘b’ ],
Equiv[ 1003, ‘c’ ],
Equiv[ 2098, ‘x’ ],
Equiv[ 3143, ‘z’ ]
]
legal = %w|a b c d e f g|
p possible & legal
#=> [#<Equiv:0x283203c @equiv=“a”, @data=1001>, #<Equiv:0x2832000
@equiv=“b”, @data=1002>, #<Equiv:0x2831fc4 @equiv=“c”, @data=1003>]
So, going back to the original problem (which has long since been
solved), we can do this instead:
require ‘equiv’
objs_as_attributes = list.map{ |obj| Equiv[ obj, obj.attribute ] }
acceptable_obj_wrappers = objs_as_attributes &
list_of_acceptable_values
acceptable_objs = acceptable_obj_wrappers.map{ |eq| eq.data }
Obviously that’s too much work. I smell an interesting approach for
automatically treating one type of object as another:
module Enumerable
def treat_as( method )
result = yield map{|obj| Equiv[obj, obj.send(method)]}
if result.is_a? Equiv
result.data
else
result.map{ |obj| obj.is_a?( Equiv ) ? obj.data : obj }
end
end
end
Person = Struct.new( :name, :age )
people = [
Person.new( ‘Gavin’, 33 ),
Person.new( ‘Bob’, 35 ),
Person.new( ‘Jim’, 40 ),
Person.new( ‘Lisa’, 32 ),
Person.new( ‘Sam’, 30 )
]
legal_ages = [ 32, 33 ]
legal_people = people.treat_as( :age ){ |people_as_ages|
people_as_ages & legal_ages
}
p legal_people
#=> [#<struct Person name=“Gavin”, age=33>, #<struct Person
name=“Lisa”, age=32>]
oldest = people.treat_as( :age ){ |people_as_ages| people_as_ages.max
}
p oldest
#=> #<struct Person name=“Jim”, age=40>
This smells wrong applying only to Enumerables, but I’m too busy to
really think this through. Just thought I’d share the idea.