I have an object for which equality tests take a long time, and I
have lots of others to compare it with. It is
an instance variable of my class, and it is also accessble by
attr_accessor. I'd like to hold a hash (number not Hash.new()) for
this object so I can compare it quickly with another. How do I detect that
it has changed so that the hash gets updated correctly? Does attr_accessor
construct code that leaves the right hooks in to detect this, or
must I write my own? Should attr_accessor do that if it doesn't?
Can I trap this by interposing in freeze tests, somehow?
If this is a code smell, how should I handle frequently queried,
slow-to-test, but changing instance variables? Make them all observables
and use update()? (That sounds expensive.)
I think the simplest solution it to define your own attribute writer
and always use it:
class Test
attr_reader :my_attribute
def my_attribute=(val) @my_attribute = val @my_attribute_hash = make_hash(val)
end
def some_other_method
# Do this
my_attribute = something_new
# Not this! @my_attribute = something_else
end
end
regards,
Ed
···
On Thu, Oct 20, 2005 at 09:01:45PM +0900, Hugh Sasse wrote:
I'd like to hold a hash (number not Hash.new()) for this object so I
can compare it quickly with another. How do I detect that it has
changed so that the hash gets updated correctly?
If only I could add it to object. I've tried, but _Why's metastuff
confuses me just sufficiently to stop me making the transition.
Given metaid.rb thusly:
<quote>
#!/usr/local/bin/ruby -w
···
On Fri, 21 Oct 2005, Edward Faulkner wrote:
On Thu, Oct 20, 2005 at 09:01:45PM +0900, Hugh Sasse wrote:
> I'd like to hold a hash (number not Hash.new()) for this object so I
> can compare it quickly with another. How do I detect that it has
> changed so that the hash gets updated correctly?
I think the simplest solution it to define your own attribute writer
and always use it:
#
# Due to Whytheluckystiff.
# http://www.whytheluckystiff.net/articles/seeingMetaclassesClearly.html
# Reformatted to work around bugs in vim indent.
#
#
class Object
# The hidden singleton lurks behind everyone
def metaclass
class << self
self
end
end
def meta_eval &blk
metaclass.instance_eval &blk
end
# Adds methods to a metaclass
def meta_def name, &blk
meta_eval { define_method name, &blk }
end
# Defines an instance method within a class
def class_def name, &blk
class_eval { define_method name, &blk }
end
end
</quote>
and hashing.rb thusly:
<quote>
#!/usr/local/bin/ruby -w
#
# Make a class keep its hash up to date by using
# accessor methods that call hash on update.
#
# Hugh Sasse
# created: 20-OCT-2005
#
#
class Object
def self.attr_hashing( *arr )
attr_reader *arr
arr.each do |var|
meta_def var do |val| @var
end
vareq = (var.to_s + "=")
meta_def vareq do |val|
instance_variable_set( "@#{var}", val )
self.hash
end
end
=begin
class_def :initialize do
self.class.traits.each do |k,v|
instance_variable_set( "@#{k}", v )
end
end
=end
end
end
</quote>
which I've produced from some badly aimed kicks at Dwemthy's Array,
I can't actually get the results I'd like.
<quote>
#!/usr/local/bin/ruby -w
#
# Test out the hashing prog.
#
require 'hashing'
class Wombat
attr_hashing :wom, :bat
attr_reader :thehash
x = Wombat.new # produce the hash message
puts x
puts x.wom
puts x.bat
puts x.methods.sort.join(', ')
x.wom = "WOM" # produce the hash message
puts x.wom
x.bat = "BAT" # produce the hash message
puts x.bat
</quote>