콘텐츠 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

공식 Ruby FAQ

If you wish to report errors or suggest improvements for this FAQ, please go to our GitHub repository and open an issue or pull request.

구문

즉시 값(immediate value)과 참조의 차이점은 무엇인가요?

This section or parts of it might be out-dated or in need of confirmation.

Fixnum, true, nil, false는 즉시 값으로 구현되어 있습니다. 즉시 값을 사용하면 변수는 객체에 대한 참조가 아니라 객체 자체를 보유합니다.

이러한 객체에는 싱글턴 메서드를 정의할 수 없습니다. 동일한 값을 가진 두 개의 Fixnum은 항상 동일한 객체 인스턴스를 나타내므로, (예를 들어) 값이 1Fixnum에 대한 인스턴스 변수는 시스템의 모든 1에 공유됩니다. 따라서 이 중 하나에 대해서만 싱글톤 메서드를 정의하는 것은 불가능합니다.

nilfalse의 차이점은 무엇인가요?

먼저 유사성부터 설명하겠습니다. nilfalse는 불 컨텍스트에서 false로 평가되는 유일한 두 개의 객체입니다. (즉, 이 둘은 유일한 “falsy” 값이며 다른 모든 객체는 “truthy”입니다.)

그러나 nilfalse는 서로 다른 클래스(NilClassFalseClass)의 인스턴스이며, 다른 곳에서는 다른 동작을 합니다.

술어(predicate) 메서드(이름이 물음표로 끝나는 메서드)는 true 또는 false를 반환하는 것이 좋습니다. 실패를 표시해야 하는 다른 메서드는 nil을 반환하는 것이 좋습니다.

빈 문자열이 false가 아닌 이유는 무엇인가요?

Q: 조건 표현식에서 빈 문자열("")이 true를 반환하던데요! Perl에서는 false였는데…

A: 하지만 Ruby는 Perl이 아닙니다. ;-) Ruby에서는 조건부 컨텍스트에서 nilfalse만 거짓입니다.

empty?를 사용하거나, 문자열을 ""와 비교하거나, 문자열의 size, length0과 비교하여 문자열이 비어 있는지 확인할 수 있습니다.

:name은 무엇을 의미하나요?

이름 뒤에 콜론을 붙이면 식별자와 일대일로 대응하는 심볼 객체가 생성됩니다. 프로그램이 실행되는 동안 주어진 이름이나 문자열에 대해 동일한 심볼 객체가 생성됩니다. 심볼은 "name".intern 또는 "name".to_sym으로 생성할 수도 있습니다.

심볼 객체는 메서드, 변수 등에 대한 식별자를 나타낼 수 있습니다. define_method, method_missing, trace_var와 같은 일부 메서드에는 심볼이 필요합니다. 다른 메서드(예: attr_accessor, send, autoload)는 문자열도 허용합니다.

심볼은 한 번만 생성되기 때문에 해시 키로 자주 사용됩니다. 문자열 해시 키는 매번 사용할 때마다 새 객체를 생성하므로 약간의 메모리 오버헤드가 발생합니다. 심볼 해시 키를 위한 특별한 구문도 있습니다.

person_1 = { :name => "John", :age => 42 }
person_2 = { name: "Jane", age: 24 }        # 대안 문법

심볼을 열거형 값으로 사용하거나 상수에 고유한 값을 할당하는 데에도 사용할 수 있습니다.

status = :open  # :closed, ...

NORTH = :NORTH
SOUTH = :SOUTH

심볼의 값에 액세스하려면 어떻게 해야 하나요?

심볼에 해당하는 변수의 값을 얻으려면 symbol.to_s 또는 "#{symbol}"을 사용하여 변수 이름을 얻은 다음 심볼의 스코프에서 이를 평가하여 변수의 내용을 얻을 수 있습니다.

a = "This is the content of `a'"
b = eval("#{:a}")
a.object_id == b.object_id  # => true

다음을 사용할 수도 있습니다.

b = binding.local_variable_get(:a)

심볼이 메서드의 이름인 경우 send를 사용할 수 있습니다.

class Demo
  def hello
    "Hello, world"
  end
end

demo = Demo.new
demo.send(:hello)

또는 Object#method를 사용하여 해당 Method 객체를 반환하게 한 다음 호출할 수 있습니다.

m = demo.method(:hello)  # => #<Method: Demo#hello>
m.call                   # => "Hello, world"

loop는 제어 구조인가요?

loop는 제어 구조체처럼 보이지만 실제로는 Kernel에 정의된 메서드입니다. loop 뒤에 오는 블록은 지역 변수에 대한 새로운 스코프를 만듭니다.

Ruby에는 사후 테스트(post-test) 루프가 없습니다.

Q: Ruby에는 do { ... } while 구문이 없는데 마지막에 조건을 테스트하는 루프를 어떻게 구현하나요?

Clemens Hintze의 답변: Ruby의 begin ... endwhile, until 문 수정자를 조합하여 동일한 효과를 얻을 수 있습니다.

i = 0
begin
  puts "i = #{i}"
  i += 1
end until i > 4

결과:

i = 0
i = 1
i = 2
i = 3
i = 4

p {}의 경우처럼 해시 리터럴을 메서드에 전달할 수 없는 이유는 무엇인가요?

{}Hash 생성자가 아닌 블록으로 파싱됩니다. p({})처럼 매개변수라는 사실을 명시하면 {}가 표현식으로 처리되도록 할 수 있습니다.

def pos=(val)가 작동하지 않습니다!

다음과 같은 코드가 있지만 pos = 1 메서드를 사용할 수 없습니다.

def pos=(val)
  @pos = val
  puts @pos
end

=가 뒤에 붙은 메서드는 명시적 수신자와 함께 호출해야 합니다(수신자 가 없으면 지역 변수에 할당하는 것뿐입니다). self.pos = 1로 호출하세요.

'\1''\\1'의 차이점은 무엇인가요?

이들은 동일한 의미를 갖습니다. 작은따옴표로 묶인 문자열에서는 \'\\만 변환되고 다른 조합은 변경되지 않습니다.

그러나 큰따옴표로 묶인 문자열에서 "\1"은 바이트 \001(8진수 비트 패턴)이고, "\\1"은 백슬래시와 문자 "1"이 포함된 두 문자로 된 문자열입니다.

.....의 차이점은 무엇인가요?

..는 범위의 오른쪽 항을 포함하지만 ...는 포함하지 않습니다.

(5..8).to_a   # => [5, 6, 7, 8]
(5...8).to_a  # => [5, 6, 7]

or||의 차이점은 무엇인가요?

Q: p(nil || "Hello")"Hello"를 출력하지만 p(nil or "Hello")는 구문 분석 오류를 발생시킵니다. 왜 그럴까요?

A: or의 우선순위가 너무 낮기 때문입니다, p( (nil or "Hello") )는 작동합니다.

or의 우선 순위는 =보다 낮지만 ||의 우선 순위는 더 높습니다.

foo = nil || "Hello"  # foo = (nil || "Hello") 로 해석
foo  # => "Hello"

# 하지만 놀랍게도

foo = nil or "Hello"  # (foo = nil) or "Hello" 로 해석
foo  # => nil

or(및 유사하게 and)는 불 표현식을 결합하는 데 사용하는 것이 아니라 다음과 같은 제어 흐름에 사용하는 것이 가장 좋습니다.

do_something  or raise "some error!"

여기서 do_something은 오류가 발생하면 false 또는 nil을 반환합니다.

Ruby에도 함수 포인터가 있나요?

Proc.new, proc, lambda에 의해 생성된 Proc 객체는 변수에서 참조할 수 있으므로 해당 변수는 함수 포인터라고 할 수 있습니다. 또한 특정 객체 인스턴스 내의 메서드에 대한 참조는 object.method를 사용하여 얻을 수 있습니다.

loadrequire의 차이점은 무엇인가요?

load는 Ruby 프로그램(*.rb)을 불러오고 실행합니다.

require는 Ruby 프로그램도 불러오지만 바이너리 Ruby 확장 모듈(공유 라이브러리 또는 DLL)도 불러옵니다. 거기에 더해 require는 기능을 두 번 이상 불러오지 않도록 합니다.

Ruby에는 예외 처리가 있나요?

Ruby는 유연한 예외 처리 체계를 지원합니다.

begin
  statements which may raise exceptions
rescue [exception class names]
  statements when an exception occurred
rescue [exception class names]
  statements when an exception occurred
ensure
  statements that will always run
end

begin 절에서 예외가 발생하면 일치하는 예외 이름을 가진 rescue 절이 실행됩니다. ensure 절은 예외 발생 여부에 관계없이 실행됩니다. rescueensure 절은 생략할 수 있습니다.

rescue 절에 대해 예외 클래스가 지정되지 않은 경우 묵시적으로 StandardError 예외를 가리키며, StandardErroris_a? 관계에 있는 예외가 캡처됩니다.

이 표현식은 begin 절의 값을 반환합니다.

가장 최근의 예외는 전역 변수 $!을 통해 액세스가 가능합니다(따라서 $!.type을 사용하여 유형을 확인할 수 있습니다).