So, then, is there no actual difference between private and protected now?
So, then, is there no actual difference between private and protected now?
https://www.ruby-lang.org/en/documentation/faq/7/
(On this page there’s a section called “What’s the difference between private and protected?” which explains it.)
It’s interesting in its own right, and it’s in my backlog to blog about because I don’t like any of the existing resources contrasting the two.
So Ruby's private only allows you to interact with other methods on the current object. Protected allows objects of the same class to send each other the message, but not other classes. Would this be a fair summary?
It's been about a year since I last looked at Ruby code (a true fave, holds it down, easy to love), but I'm pretty sure that's the idea.
In Ruby, the private keyword is more about controlling the visibility of methods rather than providing strict access control. It's a part of Ruby's philosophy of "convention over enforcement." While it does mark methods as private, it doesn't prevent you from calling them using .send. This is a design choice in Ruby to prioritize flexibility and programmer discretion.
Here's a bit more detail on how it works:
Method Visibility: When you declare a method as private, you're essentially saying that it should only be used within the class where it's defined (or its subclasses). This is a way to indicate the intended usage of a method.
No Strict Access Control: Unlike some other languages, Ruby doesn't enforce strict access control. It trusts the developer to follow conventions. However, this doesn't mean you should casually break encapsulation. It's a matter of design and discipline.
send and public_send: The send method allows you to invoke any method, including private ones, on an object. It's a powerful feature that can be handy in some situations but should be used with caution. There's also public_send, which respects the visibility rules and won't invoke private methods.
Here's an example:
class MyClass
def public_method
puts "This is a public method"
end
private
def private_method
puts "This is a private method"
end
end
obj = MyClass.new
obj.public_method # works, prints the string
obj.private_method # fails, no method
irb(main):014:0> obj = MyClass.new
=> #<MyClass:0x00000001368fd6d0>
irb(main):015:0> obj.public_method
This is a public method
=> nil
irb(main):016:0> obj.private_method
Traceback (most recent call last):
4: from /usr/bin/irb:23:in `<main>'
3: from /usr/bin/irb:23:in `load'
2: from /Library/Ruby/Gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
1: from (irb):16
NoMethodError (private method `private_method' called for #<MyClass:0x00000001368fd6d0>)
Did you mean? private_methods
irb(main):017:0> obj.send(:private_method)
This is a private method
=> nil
irb(main):018:0>I think allowing it on self. can be argued to be a pure feature -addition- rather than a -change- in which case it being in a minor release is reasonable.
(I'm not sure to what extent I buy that argument, but it at least seems like a reasonable one to make)