class Foo
tmp1 = ExpensiveObject.new
tmp2 = ExpensiveObject.new
Assuming you want to share the tmp1 and tmp2 among all instances of the
class, which probably you don’t want. Sorry.
No, I very much do - each object is only needed as a ‘scratch’ pad for
performing calculations within the method; before and after the method I
don’t care about the value. Your idea has interesting merit. I hadn’t
thought of closing and re-opening the class to ‘reset’ the closure
scope. Or (for that matter) of using define_method to create a method as
a closure as both you and David suggested.
No, I very much do - each object is only needed as a ‘scratch’ pad for performing calculations within the method; before and after the method I don’t care about the value. Your idea has interesting merit. I hadn’t thought of closing and re-opening the class to ‘reset’ the closure scope. Or (for that matter) of using define_method to create a method as a closure as both you and David suggested.
Watch out for threads, then. If your program can have multiple threads
running these calculations, a mutex will keep them from fighting over
the expensive objects.
Watch out for threads, then. If your program can have multiple threads
running these calculations, a mutex will keep them from fighting over
the expensive objects.
This got me thinking about the idea of thread local instance variables.
Thread#[] and Thread#[]= give you ‘global’ thread locals, here’s an
UNTESTED ‘SKETCH’ of a class which would let you do something like:
class Foo
def meth1 @tliv1 = ThreadLocalInstanceVariable.new
{ExpensiveVariable1.new} @tiiv2 = ThreadLocalInstanceVariable.new
{ExpensiveVariable2.new}
… do something with those expensive variables
end
…
end
rick@frodo:/public/rubyscripts$ cat thread_local.rb
require ‘delegator’
class ThreadLocalInstanceVariable < Delegator
def initialize(&init_block)
super @init_block = init_block
end
def get_obj
# thread local instance variable proxies are kept in a hash
# which is itself a thread local variable
iv_hash = Thread.current[:tl_iv_hash] || = Hash.new
local_iv = iv_hash[self.object_id]
unless local_iv
# store using object_id to avoid direct reference
my_id = self.object_id
# clean out when local iv gets GC’d, e.g. when the instance
holding
# it dies
ObjectSpace.define_finalizer(self, lambda {iv_hash.delete(my_id)})
local_iv = iv_hash[self.object_id] = init_block.call
end
local_iv
end