가시성

가시성 (Visibility)

메서드는 기본적으로 public입니다. 컴파일러는 항상 호출을 허용해요. 그래서 public 키워드는 따로 없습니다.

메서드는 privateprotected로 표시될 수 있습니다.

Private 메서드

private 메서드는 수신자(receiver) 없이, 즉 점(dot) 앞에 아무것도 없이만 호출할 수 있어요. 유일한 예외는 self를 수신자로 쓴 경우입니다:

class Person
  private def say(message)
    puts message
  end

  def say_hello
    say "hello"      # OK, no receiver
    self.say "hello" # OK, self is a receiver, but it's allowed.

    other = Person.new
    other.say "hello" # Error, other is a receiver
  end
end

private 메서드는 서브클래스에서는 볼 수 있다는 점에 주의하세요:

class Employee < Person
  def say_bye
    say "bye" # OK
  end
end

Private 타입

Private 타입은 정의된 네임스페이스 안에서만 참조할 수 있고, 절대 완전히 자격을 갖춘 형태(full qualified)로는 쓸 수 없어요.

class Foo
  private class Bar
  end

  Bar      # OK
  Foo::Bar # Error
end

Foo::Bar # Error

privateclass, module, lib, enum, alias와 상수에 쓸 수 있습니다:

class Foo
  private ONE = 1

  ONE # => 1
end

Foo::ONE # Error

Protected 메서드

protected 메서드는 다음에 대해서만 호출할 수 있어요:

  1. 현재 타입과 같은 타입의 인스턴스
  2. 현재 타입과 같은 네임스페이스(class, struct, module 등) 안의 인스턴스
# Example of 1

class Person
  protected def say(message)
    puts message
  end

  def say_hello
    say "hello"      # OK, implicit self is a Person
    self.say "hello" # OK, self is a Person

    other = Person.new "Other"
    other.say "hello" # OK, other is a Person
  end
end

class Animal
  def make_a_person_talk
    person = Person.new
    person.say "hello" # Error: person is a Person but current type is an Animal
  end
end

one_more = Person.new "One more"
one_more.say "hello" # Error: one_more is a Person but current type is the Program

# Example of 2

module Namespace
  class Foo
    protected def foo
      puts "Hello"
    end
  end

  class Bar
    def bar
      # Works, because Foo and Bar are under Namespace
      Foo.new.foo
    end
  end
end

Namespace::Bar.new.bar

protected 메서드는 자신의 클래스 또는 그 후손(descendant)의 스코프에서만 호출할 수 있습니다. 여기에는 protected 메서드가 정의된 클래스 스코프와 클래스 메서드·인스턴스 메서드의 본문뿐 아니라, 그 타입을 include하거나 상속하는 모든 타입, 그리고 그 네임스페이스 안의 모든 타입이 포함됩니다.

class Parent
  protected def self.protected_method
  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
  end

  def self.class_method
    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

Private 최상위 메서드 (Private top-level methods)

private 최상위(top-level) 메서드는 현재 파일 안에서만 볼 수 있어요.

private def greet
  puts "Hello"
end

greet # => "Hello"
require "./one"

greet # undefined local variable or method 'greet'

이렇게 하면 파일 안에서만 알 수 있는 헬퍼 메서드를 그 파일에 정의할 수 있습니다.

Private 최상위 타입 (Private top-level types)

private 최상위 타입은 현재 파일 안에서만 볼 수 있어요.

private class Greeter
  def self.greet
    "Hello"
  end
end

Greeter.greet # => "Hello"
require "./one"

Greeter.greet # undefined constant 'Greeter'

출처: Crystal 공식 문서

더 알아보기 (Learn more)