Skip to content

Instantly share code, notes, and snippets.

@pricees
Created July 13, 2012 06:20
Show Gist options
  • Save pricees/3103091 to your computer and use it in GitHub Desktop.
Save pricees/3103091 to your computer and use it in GitHub Desktop.
The curious behaviors of public, private and protected methods in Ruby
#
# The interesting world of public, private, and protected.
#
# Publics - Work as expected
#
# Privates - Work as expected, except:
# You can send a symbol of the private method as an end around
# Classes can call the privates of their superclasses
#
# Protected - Instances of the same class can call each others protecteds, whut?!
#
class Parent
# public by default
attr_accessor :name
def initialize(name = 'John Doe')
@name = name
end
def public_method
puts "I am a public method of Parent"
end
def call_protected_for(other_parent)
other_parent.protected_method
end
protected
def protected_method
puts "I am a protected method of #@name"
end
private
def private_method
puts "I am a private method of Parent"
end
public
def say_hello_to(parent)
puts "#@name: Hello, #{parent.name}!"
end
end
class Child < Parent
def initialize(name = 'John Doe')
super
end
def call_private_of_parent
puts "I am going to call my parents private_method"
private_method
end
private
def child_private_method
puts "I am a private method of #@name"
end
protected
def child_protected_method
puts "I am a protected method of #@name"
end
end
parent = Parent.new
parent1 = Parent.new "Jane Doe"
child = Child.new "Jack Doe"
#
# Try to call a protect
#
begin
parent.protected_method
rescue Exception => e
puts e
# ... protected method `protected_method' called ...
end
#
# Sibling instances, can call each others protecteds
#
parent.call_protected_for parent1
#
# Don't forget about the descendents calling protecteds on ancestors
#
child.call_protected_for parent
#
# ...and vice versa
#
parent.call_protected_for child
#
# Public keyword, you know what to do
#
parent1.say_hello_to child
#
# Descendents can call their ancestors privates private methods
#
child.call_private_of_parent
#
# Private methods are protected right?
#
begin
child.child_private_method
rescue Exception => e
puts e
end
#
# Nope, I can just send the symbol
#
child.send :child_private_method
#
# Or I can be reckless, and open up the parent class
#
class Child
public :child_private_method
end
child.child_private_method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment