_If you wish to report errors or suggest improvements for this FAQ,
please go to our
[GitHub repository](https://github.com/ruby/www.ruby-lang.org/)
and open an issue or pull request._


## 구문

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

<div class="not-prose bg-ruby-100 dark:bg-ruby-800 rounded-lg p-8 my-6">
  <div class="flex items-start gap-3">
    <svg class="w-6 h-6 text-ruby-700 dark:text-ruby-200 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
      <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd"/>
    </svg>
    <p class="text-sm text-ruby-700 dark:text-ruby-200 italic">
      This section or parts of it might be out-dated or in need of confirmation.
    </p>
  </div>
</div>


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

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

### `nil`과 `false`의 차이점은 무엇인가요?

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

그러나 `nil`과 `false`는 서로 다른 클래스(`NilClass`와 `FalseClass`)의
인스턴스이며, 다른 곳에서는 다른 동작을 합니다.

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

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

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

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

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

### `: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 ... end`와 `while`, `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`를 사용하여 얻을 수 있습니다.

### `load`와 `require`의 차이점은 무엇인가요?

`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` 절은 예외 발생 여부에 관계없이 실행됩니다. `rescue` 및
`ensure` 절은 생략할 수 있습니다.

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

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

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