Infinite loop with Singleton mixin


#1

This loops inifitely, but it doesn’t seem like it should.


require ‘singleton’

class SingleThing
include Singleton
def initialize
@a = OtherThing.new
end
end

class OtherThing
def initialize
@single_ref = SingleThing.instance
end
end

a = SingleThing.instance


It looks as if the the SingleThing.instance method doesn’t start
returning the allocated instance until initialize has finished, but it
seems to me it should start returning the allocated instance as soon as
initialize starts. Otherwise, methods called during initialize (and
the methods they call, and so on) can’t refer back to the singleton
object using SingleThing.instance.

Any thoughts?


#2

Hi,

In message “Re: Infinite loop with Singleton mixin”
on Wed, 25 Feb 2009 13:45:41 +0900, Adam G.
removed_email_address@domain.invalid writes:

|This loops inifitely, but it doesn’t seem like it should.

Uninitialized singleton object should not be disclosed, I think. So I
think it should loop infinitely, as you specified.

          matz.

#3

Yukihiro M. wrote:

Hi,

In message “Re: Infinite loop with Singleton mixin”
on Wed, 25 Feb 2009 13:45:41 +0900, Adam G.
removed_email_address@domain.invalid writes:

|This loops inifitely, but it doesn’t seem like it should.

Uninitialized singleton object should not be disclosed, I think. So I
think it should loop infinitely, as you specified.

          matz.

Personally, I disagree. I think both consistency and utility would be
better served by having .instance return the instance as soon as
initialize has started - after all, there are plenty of other ways to
get references to objects which haven’t finished their initialize
function, and they don’t cause undue trouble. But I can understand why
it might need to be the way it is. I’ll try and work around it.

Incidentally, it turns out the code above isn’t looping the way I
thought it was; it’s actually stuck inside the while loop in
singleton.rb:148-152

while false.equal?(@instance)
Thread.critical = false
sleep(0.08) # timeout
Thread.critical = true
end

Which, itself, suggests a work-around:


require ‘singleton’

class SingleThing
include Singleton
def initialize
self.class.instance_variable_set(:@instance,self)
@a = OtherThing.new
end
end

class OtherThing
def initialize
@single_ref = SingleThing.instance
end
end

a = SingleThing.instance

Anyway, thanks for your attention, and thank you for your hard work on
Ruby.