public / private / protected
Keywords for controlling method access (visibility) in Ruby. They restrict calls from outside the object to achieve encapsulation.
Syntax
class ClassName
# public: Callable from anywhere (default).
public
def public_method
# process
end
# private: Callable only from within the class (self).
private
def private_method
# process
end
# protected: Callable from instances of the same class and subclasses.
protected
def protected_method
# process
end
# Ruby 2.1+: You can also pass a method name directly as an argument.
private :method_name
private def method_name; end
end
Method List
| Keyword | Description |
|---|---|
| public | Defines a method callable from anywhere. Accessible from outside the class as well. This is the default visibility. |
| private | Defines a method callable only from within the class. Cannot be called from outside the class or from another instance. |
| protected | Defines a method callable from instances of the same class or subclasses. Useful for comparison methods and similar use cases. |
| send(:method_name) | Calls a method by name, including private methods. Used for testing and dynamic dispatch. |
| public_send(:method_name) | Calls only public methods. Raises a NoMethodError for private methods. |
Sample Code
class BankAccount
attr_reader :balance
def initialize(owner, balance)
@owner = owner
@balance = balance
end
# public: Callable from outside the class.
def deposit(amount)
validate_amount(amount) # Calls a private method from within the class.
@balance += amount
puts "Deposited #{amount}. Balance: #{@balance}"
end
def >(other)
balance > other.balance # Accesses a protected method on another instance.
end
private
# private: Cannot be called from outside the class.
def validate_amount(amount)
raise ArgumentError, "Amount must be a positive number" if amount <= 0
end
protected
# protected: Callable between instances of the same class (used for balance comparison).
def balance
@balance
end
end
account_a = BankAccount.new("Alice", 10000)
account_b = BankAccount.new("Bob", 5000)
account_a.deposit(3000) # Deposited 3000. Balance: 13000
puts account_a > account_b # true (uses protected method internally for comparison)
# Calling a private method from outside raises NoMethodError.
begin
account_a.validate_amount(100)
rescue NoMethodError => e
puts "Error: #{e.message}" # Error: private method 'validate_amount' called...
end
Overview
public is the default visibility, allowing a method to be called from anywhere outside the class. private restricts calls to within the class itself — it cannot be called from outside the class or from a different instance of the same class. protected sits in between, allowing calls only between instances of the same class or subclasses.
protected is mainly used for methods that compare instances of the same class. As shown in the example above, it is useful when you need to access data on another instance when implementing comparison operators.
Unlike Java and similar languages, Ruby's private works by prohibiting calls with an explicit receiver. Before Ruby 2.7, calling a private method as self.private_method was also prohibited, but since Ruby 2.7, self.private_method is allowed.
For the basics of class definitions, see class / initialize / attr_accessor. For details on self and class methods, see self / instance variables / class variables.
If you find any errors or copyright issues, please contact us.