Created
July 13, 2012 06:20
-
-
Save pricees/3103091 to your computer and use it in GitHub Desktop.
The curious behaviors of public, private and protected methods in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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