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:

    1. class Employee < Person
    2. def say_bye
    3. say "bye" # OK
    4. end
    5. end

    Private types can only be referenced inside the namespace where they are defined, and never be fully qualified.

    1. class Foo
    2. private ONE = 1
    3. ONE # => 1
    4. end

    A protected method can only be invoked on:

    1. instances of the same type as the current type
    2. 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.

    1. class Parent
    2. end
    3. Parent.protected_method # OK
    4. def instance_method
    5. Parent.protected_method # OK
    6. end
    7. def self.class_method
    8. Parent.protected_method # OK
    9. end
    10. end
    11. class Child < Parent
    12. Parent.protected_method # OK
    13. def instance_method
    14. Parent.protected_method # OK
    15. Parent.protected_method # OK
    16. end
    17. end
    18. class Parent::Sub
    19. Parent.protected_method # OK
    20. def instance_method
    21. Parent.protected_method # OK
    22. end
    23. def self.class_method
    24. Parent.protected_method # OK
    25. end
    26. 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”

    1. ```crystal title="two.cr"
    2. require "./one"
    3. Greeter.greet # undefined constant 'Greeter'