기타 문법

기타 문법 (Miscellaneous Syntax)

앞서 다룬 문법들에 속하지 않는, 그래도 알아두면 쓸모 있는 Ruby 문법 조각들을 모아볼게요. 표현식 끝맺음, 들여쓰기, 그리고 몇 가지 유용한 키워드들까지 차례로 살펴봐요.

출처: Ruby 공식 문서

본문

표현식의 끝 (Ending an Expression)

Ruby는 줄바꿈(newline)을 표현식의 끝으로 봐요. 다만 줄을 연산자(operator), 열린 괄호, 쉼표 같은 것으로 끝내면 표현식은 다음 줄로 이어져요.

표현식을 세미콜론(;)으로 끝낼 수도 있어요. 세미콜론은 특히 ruby -e와 함께 쓸 때 가장 자주 등장해요.

들여쓰기 (Indentation)

Ruby는 들여쓰기를 요구하지 않아요. 다만 관례상 Ruby 프로그램은 두 칸을 들여 쓰는 경우가 일반적이에요.

경고(warnings)를 켠 상태로 ruby를 실행했는데 들여쓰기가 어긋나 있으면, Ruby가 경고를 알려줘요.

alias

alias 키워드는 메서드에 별명을 붙일 때 가장 많이 쓰여요. 메서드에 별명을 붙일 때는 그 이름이나 심볼 둘 다 사용할 수 있어요.

alias new_name old_name
alias :new_name :old_name

메서드의 경우에는 alias 대신 Module#alias_method를 쓸 수 있을 때가 많아요.

alias를 이용해 전역 변수에도 별명을 붙일 수 있어요.

$old = 0

alias $new $old

p $new # prints 0

alias는 어떤 스코프에서든 사용할 수 있어요.

undef

undef 키워드는 현재 클래스가 이름이 주어진 메서드 호출에 응답하지 않도록 막아요.

undef my_method

메서드 이름 대신 심볼을 쓸 수도 있어요.

undef :my_method

여러 메서드를 한 번에 지울 수도 있어요.

undef method1, method2

undef는 어떤 스코프에서든 사용할 수 있어요. Module#undef_method도 함께 알아두면 좋아요.

defined?

defined?는 인자를 설명하는 문자열을 돌려주는 키워드예요.

p defined?(UNDEFINED_CONSTANT) # prints nil
p defined?(RUBY_VERSION)       # prints "constant"
p defined?(1 + 1)              # prints "method"

defined?에는 괄호를 쓰지 않아도 되지만, defined?의 우선순위가 낮기 때문에 괄호를 쓰는 편을 권해요.

예를 들어 인스턴스 변수가 존재하는지, 그리고 그 인스턴스 변수가 0인지 확인하고 싶다면 이렇게 쓸 수 있어요.

defined? @instance_variable && @instance_variable.zero?

그런데 이 경우 인스턴스 변수가 정의되어 있지 않으면 "expression"을 돌려줘서, 원하는 결과가 아니에요.

@instance_variable = 1
defined?(@instance_variable) && @instance_variable.zero?

인스턴스 변수가 정의되어 있는지 확인할 때 괄호를 붙이면 더 정확한 검사가 돼요. 이렇게 하면 인스턴스 변수가 정의되어 있지 않을 때는 nil을, 0이 아닐 때는 false를 올바르게 돌려줘요.

인스턴스 변수에는 instance_variable_defined? 같은 반영(reflection) 메서드를, 상수에는 const_defined?를 쓰는 편이 defined?를 쓰는 것보다 실수를 덜 유발해요.

defined?는 일부 정규식 전역 변수를 특별히 다루는데, 활성화된 정규식 매치가 있는지, 그리고 캡처 그룹이 몇 개인지에 따라 결과가 달라져요.

/b/ =~ 'a'
defined?($~) # => "global-variable"
defined?($&) # => nil
defined?($`) # => nil
defined?($') # => nil
defined?($+) # => nil
defined?($1) # => nil
defined?($2) # => nil

/./ =~ 'a'
defined?($~) # => "global-variable"
defined?($&) # => "global-variable"
defined?($`) # => "global-variable"
defined?($') # => "global-variable"
defined?($+) # => nil
defined?($1) # => nil
defined?($2) # => nil

/(.)/ =~ 'a'
defined?($~) # => "global-variable"
defined?($&) # => "global-variable"
defined?($`) # => "global-variable"
defined?($') # => "global-variable"
defined?($+) # => "global-variable"
defined?($1) # => "global-variable"
defined?($2) # => nil

BEGIN과 END

BEGIN은 현재 파일에서 다른 코드보다 먼저 실행되는 블록을 정의해요. 주로 ruby -e를 쓰는 한 줄짜리 코드에서 써요. 마찬가지로 END는 다른 코드가 모두 실행된 뒤에 실행되는 블록을 정의해요.

BEGIN은 반드시 최상위(top-level)에 나타나야 하고, END는 메서드 안에서 쓰면 경고가 나와요.

다음은 그 예시예요.

BEGIN {
  count = 0
}

{}를 써야 하며, doend는 사용할 수 없어요.

표준 입력이나 인자 목록에 있는 파일에서 숫자를 더하는 한 줄짜리 예시를 볼게요.

ruby -ne 'BEGIN { count = 0 }; END { puts count }; count += gets.to_i'

더 알아보기 (Learn more)