[BUG] Strange weak-ref behaviour

Hi. Take a look at the source code at the end of the email and run it.
The expected output for me is, either an empty string ("") or nothing
(and this up to 1000 times). But, the output I get (on both Ruby 1.8.x
and 1.9) is like that shown below:

  "w.rb:16:in `_id2ref'"
  ["w.rb:16:in `_id2ref'", "w.rb:16:in `each_object'", "w.rb:14:in
  `each'", "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'",
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'", "w.rb:14:in
  `each_object'", "w.rb:30"]
  "w.rb:16:in `_id2ref'"
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'"
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'"
  "w.rb:14:in `each'"
  #<RangeError: 0x4086550 is recycled object>
  ["w.rb:16:in `_id2ref'", "w.rb:16:in `each_object'", "w.rb:14:in
  `each'", "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'",
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'", "w.rb:14:in
  `each_object'", "w.rb:30"]
  #<RangeError: 0x4084e1c is recycled object>
  "w.rb:14:in `each'"
  "w.rb:14:in `each_object'"
  "w.rb:14:in `each'"
  "w.rb:16:in `_id2ref'"
  "w.rb:14:in `each_object'"
  "w.rb:30"

There must be something wrong, or is this correct? Does Ruby reuse
object_id's? BTW, what happens if an application uses more than 4 billon
(32-bit) objects? Does Ruby fail or reuse old object_ids?

Thanks in advance.

Regards,

  Michael

···

#################################
# here the code. if no output is shown, try to
# increase the number of objects registered (1000)
#
  require 'set'

  class StateRegistry

    def initialize
      @registered_objects = Set.new
    end

    def register(obj)
      @registered_objects.add(obj.object_id)
    end

    def each_object
      @registered_objects.each do |oid|
        begin
          obj = ObjectSpace._id2ref(oid)
        rescue RangeError
          next
        end
        yield obj
      end
    end
  end

  s = StateRegistry.new
  1000.times do
    s.register("")
  end
  ObjectSpace.garbage_collect
  s.each_object {|obj| p obj}

There must be something wrong, or is this correct?

correct.

Does Ruby reuse object_id's?

it can

Guy Decoux

I may be confused, but I do not see where you are even using using
weak-refs. It looks like you are doing something like this:

      * 1000 times
              * Making an object
              * Noting its id
              * Setting it free to wander in the woods unreferenced
      * Sending the wolf into the woods to hunt unreferenced objects
      * Calling for it by id
      * Being surprised to hear that it is no longer with us

This does not look like a bug to me (I wouldn't expect them to answer
after I've set the wolf on them), but I may be misunderstanding.

-- Markus

···

On Sat, 2004-10-23 at 16:51, Michael Neumann wrote:

Hi. Take a look at the source code at the end of the email and run it.
The expected output for me is, either an empty string ("") or nothing
(and this up to 1000 times). But, the output I get (on both Ruby 1.8.x
and 1.9) is like that shown below:

  "w.rb:16:in `_id2ref'"
  ["w.rb:16:in `_id2ref'", "w.rb:16:in `each_object'", "w.rb:14:in
  `each'", "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'",
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'", "w.rb:14:in
  `each_object'", "w.rb:30"]
  "w.rb:16:in `_id2ref'"
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'"
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'"
  "w.rb:14:in `each'"
  #<RangeError: 0x4086550 is recycled object>
  ["w.rb:16:in `_id2ref'", "w.rb:16:in `each_object'", "w.rb:14:in
  `each'", "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each_key'",
  "/home/mneumann/usr/lib/ruby/1.9/set.rb:193:in `each'", "w.rb:14:in
  `each_object'", "w.rb:30"]
  #<RangeError: 0x4084e1c is recycled object>
  "w.rb:14:in `each'"
  "w.rb:14:in `each_object'"
  "w.rb:14:in `each'"
  "w.rb:16:in `_id2ref'"
  "w.rb:14:in `each_object'"
  "w.rb:30"

There must be something wrong, or is this correct? Does Ruby reuse
object_id's? BTW, what happens if an application uses more than 4 billon
(32-bit) objects? Does Ruby fail or reuse old object_ids?

Thanks in advance.

Regards,

  Michael

#################################
# here the code. if no output is shown, try to
# increase the number of objects registered (1000)
#
  require 'set'

  class StateRegistry

    def initialize
      @registered_objects = Set.new
    end

    def register(obj)
      @registered_objects.add(obj.object_id)
    end

    def each_object
      @registered_objects.each do |oid|
        begin
          obj = ObjectSpace._id2ref(oid)
        rescue RangeError
          next
        end
        yield obj
      end
    end
  end

  s = StateRegistry.new
  1000.times do
    s.register("")
  end
  ObjectSpace.garbage_collect
  s.each_object {|obj| p obj}

Excuse my stupidity. Of course I should define a finalizer (and should
not write emails that early in the morning :).

Regards,

  Michael

···

On Sun, Oct 24, 2004 at 05:45:08PM +0900, ts wrote:

> There must be something wrong, or is this correct?

correct.

Correct. It isn't a bug! I got confused, as I thought, object_id's would
not be reused.

Regards,

  Michael

···

On Mon, Oct 25, 2004 at 11:27:31PM +0900, Markus wrote:

     I may be confused, but I do not see where you are even using using
weak-refs. It looks like you are doing something like this:

      * 1000 times
              * Making an object
              * Noting its id
              * Setting it free to wander in the woods unreferenced
      * Sending the wolf into the woods to hunt unreferenced objects
      * Calling for it by id
      * Being surprised to hear that it is no longer with us

This does not look like a bug to me (I wouldn't expect them to answer
after I've set the wolf on them), but I may be misunderstanding.