# ObjectSpace searching

**URL:** <https://www.ruby-forum.com/t/objectspace-searching/57342>\
**Category:** Ruby\
**Created:** [April 10, 2006, 5:08am UTC](https://www.ruby-forum.com/t/objectspace-searching/57342 "2006-04-10T05:08:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [April 10, 2006, 5:08am UTC](https://www.ruby-forum.com/t/objectspace-searching/57342/1 "2006-04-10T05:08:19Z")

</div>

I wrote some code that searches ObjectSpace prior to initializing an  
object to see if one of that type and some attributes is already  
present and uses that instead of initializing. (yes it’s active record  
and i am trying to avoid stale object errors). How horrible is this? I  
am searching by specific class name so in practice it ends up looking  
at at most a couple of instances but is there something inherently  
wrong with doing this?

def find\_in\_space(search\_id, search\_version = nil)  
retval = nil  
ObjectSpace.each(Person){|person|  
retval = person if (p.id == search\_id) &&  
search\_version &&  
p.lock\_version == search\_version  
}  
return retval || Person.find(search\_id)  
end

Mark

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [April 10, 2006, 8:07am UTC](https://www.ruby-forum.com/t/objectspace-searching/57342/2 "2006-04-10T08:07:27Z")

</div>

On Apr 9, 2006, at 8:06 PM, Mark Alexander F. wrote:

> ObjectSpace.each(Person){|person|  
> retval = person if (p.id == search\_id) &&  
> search\_version &&  
> p.lock\_version == search\_version  
> }  
> return retval || Person.find(search\_id)  
> end

For one, you could fail early:

s = ‘foo’  
obj = nil  
ObjectSpace.each\_object(String) { |str| if str.equal? s then obj =  
str; break; end }  
p obj # =\> ‘foo’

Really, you should handle errors properly. This code won’t eliminate  
the possibility of a double-update, another process can cause them to  
happen after this code gets run.

(Also, you should use cached\_model and turn on its local cache. Much  
more efficient than traversing ObjectSpace.)

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![mfaine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b3f665/32.png) [@mfaine](https://www.ruby-forum.com/u/mfaine)\
**Post date:** [April 10, 2006, 4:33pm UTC](https://www.ruby-forum.com/t/objectspace-searching/57342/3 "2006-04-10T16:33:36Z")

</div>

2006/4/10, Mark Alexander F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ObjectSpace.each(Person){|person|  
> retval = person if (p.id == search\_id) &&  
> search\_version &&  
> p.lock\_version == search\_version  
> }  
> return retval || Person.find(search\_id)  
> end

This is bound to be slow. The easiest improvement you can do is to  
have the return inside the block. But even that will not change the  
order of magnitude (both approaches are O(n)).

Also, you seem to have a bug in there - you frequently use “p.” where  
it should probably rather read “person.”.

If you do those lookups frequently, I’d rather consider using an  
approach that uses a hash inside the class object.

# example

class Person  
attr\_reader :id  
def initialize(id) @id = id end

@instances = Hash.new {|h,k| h[k] = [new(k)]}

def self.get(search\_id, search\_version = nil)  
arr = @instances[search\_id]  
arr.each {|per| return per if search\_version == per.lock\_version}  
if search\_version  
arr[0]  
end  
end

I don’t know what exactly you need the version for but the asymmetry  
(with and without version) strikes me as odd.

Kind regards

robert
