Forum: Ruby ObjectSpace searching

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A50362426c2bc7d040ad4c0a69f57527?d=identicon&s=25 Mark Alexander Friedgan (Guest)
on 2006-04-10 05:08
(Received via mailing list)
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
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-04-10 08:07
(Received via mailing list)
On Apr 9, 2006, at 8:06 PM, Mark Alexander Friedgan 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 Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2006-04-10 16:33
(Received via mailing list)
2006/4/10, Mark Alexander Friedgan <hubrix@gmail.com>:
>   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
This topic is locked and can not be replied to.