Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

루비 별칭(alias) 키워드 완벽 가이드: alias vs alias_method 차이점

루비에서는 메서드에 새로운 이름(별칭)을 부여하는 두 가지 방법이 있습니다.

  • alias (키워드)
  • alias_method (메서드)

두 방식은 기능적으로 같은 일을 수행하지만 동작 방식에 미묘한 차이가 있어 많은 개발자를 혼란스럽게 만드는 주제입니다.

아래 이미지는 두 방식의 차이를 한눈에 정리한 것입니다:

루비 별칭(alias) 키워드 완벽 가이드: alias vs alias_method 차이점

지금부터 이 차이점들을 하나씩 자세히 살펴보며 확실하게 이해해 보겠습니다!

alias 키워드

먼저 alias는 루비의 키워드입니다(if, def, class 등과 같은 종류).

사용 형태는 다음과 같습니다:

alias print_something puts

print_something 1

이제 print_something을 호출하면 puts를 호출하는 것과 동일하게 동작합니다.

alias는 키워드이기 때문에 몇 가지 흥미로운 특징을 가집니다:

  • 고유한 특수 문법을 가집니다
  • 코드 어디에서든 사용할 수 있습니다
  • 전역 변수에도 별칭을 붙일 수 있습니다 (하지만 절대 이렇게 하지 마세요!)

alias의 유효한 문법 형태는 다음과 같습니다:

  • alias a b
  • alias :a :b
  • alias :"#{}" :b

주목할 점은 일반 메서드 호출과 달리 인자 사이에 쉼표가 없다는 것입니다.

루비는 ab가 유효한 메서드 이름(심볼)이기를 기대하며, 변수는 그대로 사용할 수 없습니다. 변수를 활용하고 싶다면 아래처럼 문자열 보간을 사용해야 합니다.

예제:

a = :print_something
b = :puts

alias :"#{a}" :"#{b}"

하지만 다소 지저분해 보이기 때문에, 동적인 메서드 이름에는 alias_method를 사용하는 것이 좋습니다.

alias_method 메서드

다음은 Module에 정의된 메서드인 alias_method입니다.

이 메서드는 클래스 및 모듈 레벨에서만 사용할 수 있으며, 인스턴스 메서드 내부에서는 사용할 수 없습니다.

공식 문서의 설명은 다음과 같습니다:

alias_method: "new_nameold_name 메서드의 새로운 복사본으로 만듭니다. 오버라이드되어 사라진 메서드에 대한 접근을 유지하는 데 유용합니다."

예제:

class Foo
  alias_method :print_something, :puts
end

이렇게 하면 Foo 클래스 내부에서 print_somethingputs의 별칭이 됩니다.

alias_method는 인자로 심볼뿐 아니라 문자열도 사용할 수 있습니다.

예제:

class Foo
  alias_method "print_something", "puts"
end

alias vs alias_method: 언제 차이가 발생할까?

지금까지 aliasalias_method의 개요를 살펴봤습니다. 그렇다면 실질적인 차이는 언제 드러날까요?

  1. 동적으로 생성된 메서드 이름(예: "abc#{rand}")에 별칭을 붙일 때
  2. 메서드 내부에서 별칭을 정의할 때

동적으로 생성된 메서드 이름에 별칭을 붙이는 것은 alias 키워드로도 가능하지만, 보간된 심볼을 사용해야 하는 번거로움이 있습니다. 반면 alias_method는 훨씬 유연한 인자를 제공합니다.

예제:

class Cat
  def speak
    "meow"
  end

  alias_method "#{name.downcase}_speak", :speak
end

p Cat.new.cat_speak
# "meow"

그리고, 메서드 내부에서 별칭을 정의하려고 하면 다음과 같은 에러가 발생합니다:

undefined method 'alias_method' for #<Bacon:0x0000555b4dafb880> (NoMethodError)

이는 객체 내부에서 작업 중이지 클래스 컨텍스트가 아니기 때문입니다!

인스턴스 메서드 안에서는 alias_method가 정의되어 있는 Module의 메서드에 접근할 수 없습니다.

가능한 해결책 중 하나는 다음과 같습니다:

def enable_aliased_methods
  self.class.send(:alias_method, :x, :testing)
end

alias 키워드를 사용한다면:

def enable_aliased_methods
  alias :x :testing
end

여기서 꼭 기억해야 할 중요한 차이점이 하나 있습니다:

  • alias로 정의된 메서드는 alias작성된 그 클래스에 속합니다
  • alias_method로 정의된 메서드는 코드가 실행되는 시점의 현재 클래스, 즉 self에 속합니다

이것이 왜 중요할까요?

alias 키워드를 사용하는 메서드를 부모 클래스에서 호출하면, 별칭 생성은 해당 메서드를 호출한 클래스가 아니라 부모 클래스에서 일어납니다.

예제:

class Food
  def create_alias
    alias print_on_screen puts
  end
end

class Apple < Food
end

Apple.new.create_alias

반면 alias_method를 사용하면 별칭은 Apple 클래스에만 적용됩니다.

별칭은 메서드의 '복사본'을 만든다

alias_methodalias 키워드의 설명에서 알 수 있듯이, 루비는 메서드의 복사본을 생성합니다.

단순히 새로운 이름만 붙이는 것이 아니라 실제로 메서드 전체를 복사하는 것입니다.

이로 인해 몇 가지 실질적인 결과가 발생합니다:

def bacon
  123
end

alias :x :bacon

x
# 123

bacon
# 123

xbacon의 별칭으로 만들었습니다. 이제 bacon을 재정의하면 어떻게 될까요?

def bacon
  234
end

x
# 123

bacon
# 234

x 메서드는 여전히 123을 반환하지만, bacon은 새로운 값 234를 반환합니다!

메서드에 별칭을 붙인 후 나중에 모듈을 include하는 경우 이 동작이 의외라고 느껴질 수 있으니 주의하세요.

마무리: 어떤 것을 사용해야 할까?

일반적으로는 alias_method가 실제 메서드라는 점에서 더 선호되는 편입니다.

반면 alias 키워드는 기억하고 유지해야 할 특수한 특성들이 많아 실수하기 쉽습니다.

새로운 것을 배우셨나요? 이 글을 루비를 공부하는 친구들에게 공유해서 함께 성장해 보세요!