Why does private is applicable only for instance methods and isn't for the class methods? Not only that, why doesn't private_class_method method make the class methods private?
class Foo
private
def self.private_class_method
puts 'hello from private_class_method'
end
def private_instace_method
puts 'hello from private_instace_method'
end
end
Foo.private_class_method #Ok!
Foo.new.private_instace_method #error: private method `private_instace_method' called for #<Foo:0x000001020873b8>
How about this?
class Foo
private_class_method :private_class_method
def self.private_class_method
puts 'hello from private_class_method'
end
private
def private_instace_method
puts 'hello from private_instace_method'
end
end
Foo.private_class_method #Ok!
Foo.new.private_instace_method #error: private method `private_instace_method' called for #<Foo:0x000001020873b8>
How do I make a class method private?
You can create a private class methods like this:
class Foo
def self.will_be_private
# ...
end
private_class_method :will_be_private
end
Or like this:
class Foo
class << self
private
def will_be_private
# ...
end
end
end
While it is possible the make a class methods private, I can hardly think of a good reason to do so. IMO a private class method is a code smell and indicates that there is a thing that should be extracted into it own class.
Why does
privateis applicable only for instance methods and isn't for the class methods?
This part of the OP never got answered, and I thought it deserved to be, not least since I had the same question.
The short answer is that the private keyword is actually a method call on the instance’s class which sets the visibility for subsequently defined instance methods; unlike what it seems on first look, it's not a language keyword meaning "make everything after this point private".
More detail...
When you're defining a class method, you typically do it like this...
class SomeClass
def self.some_class_method
# ...
end
end
That self. part means that you're defining a method not on instances of the class, but on self, which is the "singleton class" for (in this case) SomeClass. Calling private affects instance methods since they're attached to the instance itself, but class methods are attached somewhere else - to the singleton class -, so aren't affected by it. By contrast, private_class_method calls set_method_visibility(rb_singleton_class(obj) so is explicitly concerned with the singleton class methods.
I found this article helpful: https://jakeyesbeck.com/2015/08/23/ruby-objects/.
Don't worry if you find this confusing - you're not the only one! I recommend experimenting with these concepts in irb to help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With