GingerJim
GingerJim

Reputation: 3907

Ruby private class method

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

Answers (2)

Chris Heald
Chris Heald

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

Sergio Tulentsev
Sergio Tulentsev

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

Related Questions