# Re: Associating data with a function

**URL:** <https://www.ruby-forum.com/t/re-associating-data-with-a-function/71069>\
**Category:** Ruby\
**Created:** [October 5, 2006, 5:45am UTC](https://www.ruby-forum.com/t/re-associating-data-with-a-function/71069 "2006-10-05T05:45:47Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [October 5, 2006, 5:45am UTC](https://www.ruby-forum.com/t/re-associating-data-with-a-function/71069/1 "2006-10-05T05:45:47Z")

</div>

From: Joel VanderWerf [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

> Joel VanderWerf wrote:
> 
> > Use closures and class scopes:
> > 
> > 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.

Thanks, interesting ideas!

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [October 5, 2006, 6:35am UTC](https://www.ruby-forum.com/t/re-associating-data-with-a-function/71069/2 "2006-10-05T06:35:50Z")

</div>

Gavin K. wrote:

> 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.

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [October 5, 2006, 7:47pm UTC](https://www.ruby-forum.com/t/re-associating-data-with-a-function/71069/3 "2006-10-05T19:47:24Z")

</div>

On 10/5/06, Joel VanderWerf [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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

end

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)
