Visibility
Methods can be marked as private
or protected
.
A private
method can only be invoked without a receiver, that is, without something before the dot. The only exception is self
as a receiver:
Note that private
methods are visible by subclasses:
class Employee < Person
def say_bye
say "bye" # OK
end
end
Private types can only be referenced inside the namespace where they are defined, and never be fully qualified.
class Foo
private ONE = 1
ONE # => 1
end
A protected
method can only be invoked on:
- instances of the same type as the current type
- instances in the same namespace (class, struct, module, etc.) as the current type
A protected
method can only be invoked from the scope of its class or its descendants. That includes the class scope and bodies of class methods and instance methods of the same type the protected method is defined on, as well as all types including or inherinting that type and all types in that namespace.
class Parent
end
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
end
def self.class_method
Parent.protected_method # OK
end
end
class Child < Parent
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
Parent.protected_method # OK
end
end
class Parent::Sub
Parent.protected_method # OK
def instance_method
Parent.protected_method # OK
end
def self.class_method
Parent.protected_method # OK
end
end
A private
top-level method is only visible in the current file.
```crystal title=”one.cr” private def greet puts “Hello” end
This allows you to define helper methods in a file that will only be known in that file.
A private
top-level type is only visible in the current file.
```crystal title=”one.cr” private class Greeter def self.greet “Hello” end end
Greeter.greet # => “Hello”
```crystal title="two.cr"
require "./one"
Greeter.greet # undefined constant 'Greeter'