Created
December 18, 2014 09:12
-
-
Save Integralist/bb8760d11a03c88da151 to your computer and use it in GitHub Desktop.
Ruby: private class level methods
This file contains hidden or 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
class Foo | |
class << self | |
def bar | |
p "im public" | |
end | |
private | |
def baz | |
p "im private" | |
end | |
end | |
end | |
Foo.bar # => im public | |
Foo.baz # => NoMethodError: private method `baz' called for Foo:Class |
This file contains hidden or 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
class Foo | |
def self.bar | |
p "im public" | |
end | |
private | |
def self.baz | |
p "im private" | |
end | |
end | |
Foo.bar # => im public | |
Foo.baz # => im private |
It has been suggested that private
is actually a method (not a directive or special syntax) and so the private
method only changes the visibility of instance methods. Class methods on the other hand are instance methods of the Eigenclass.
In the first example (class << self
) the private
method goes through the Eigenclass (so the class methods technically become instance methods on the Eigenclass and so the private
directive is enforced) but in the second example the private
method goes through the Foo
class (and its class level methods aren't affected by the private
method).
You can get the second example (def self.baz
) to work by using private_class_method :baz
...
class Foo
def self.bar
p "im public"
end
def self.baz
p "im private"
end
private_class_method :baz
end
Foo.bar # => im public
Foo.baz # => NoMethodError: private method `baz' called for Foo:Class
See also https://stackoverflow.com/a/12925407/322020 and other answers there.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Information found here (it has useful diagrams too):
http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html
When creating singleton methods (i.e.
def self.foo
) Ruby will create an anonymous class to hold these methods. The anonymous class then assumes the role of the object's class and the original class is re-designated as the superclass of that anonymous class.This means the standard "method lookup" pattern (this is how Ruby implements looking up methods on an object) is unaltered - both the singleton methods (in the anonymous class) and the instance methods (in the superclass) will be found along the method lookup path when the object receives a method call.
The anonymous class is known as an Eigenclass.
This is where the following syntax comes from (it effectively allows you to open up the eigenclass)...