Reputation: 3907
I tried to implement a singleton pattern in ruby, just want to know why I can not access private class method in ruby
class Test
private_class_method :new
@@instance = nil
def self.getInstance
if(!@@instance)
@@instance = Test.new
end
return @@instance
end
end
I declare "new" as a private class method, and try to call the "new" in my singleton method "getInstance"
test output
>> require "./test.rb"
=> true
>> Test.getInstance
NoMethodError: private method `new' called for Test:Class
from ./test.rb:7:in `getInstance'
from (irb):2
>>
Upvotes: 2
Views: 2467
Reputation: 62638
Since ::new
is a private method, you can't access it by sending a message to the class constant. It'll work to just send it to implicit self
by omitting the receiver, though.
Additionally, since this is a class method, its instance variable scope is already class-level, so you don't need to use @@
class variables. An instance variable will work just fine here.
class Test
private_class_method :new
def self.instance
@instance ||= new
end
end
puts Test.instance.object_id
puts Test.instance.object_id
# => 33554280
# => 33554280
Upvotes: 3
Reputation: 230286
private_class_method :new
NoMethodError: private method `new' called for Test:Class
That's why. Private methods cannot be invoked with explicit receiver. Try using send
.
@@instance = Test.send(:new)
or with implicit receiver (because self
is Test
)
@@instance = new
Upvotes: 2