|
| 1 | +--- |
| 2 | +layout: page |
| 3 | +title: "공식 Ruby FAQ" |
| 4 | +lang: ko |
| 5 | + |
| 6 | +header: | |
| 7 | + <div class="multi-page"> |
| 8 | + <a href="../" title="Content">콘텐츠</a> |
| 9 | + <span class="separator"> | </span> |
| 10 | + <a href="../1/" title="파트 1">1</a> |
| 11 | + <span class="separator"> | </span> |
| 12 | + <a href="../2/" title="파트 2">2</a> |
| 13 | + <span class="separator"> | </span> |
| 14 | + <a href="../3/" title="파트 3">3</a> |
| 15 | + <span class="separator"> | </span> |
| 16 | + <a href="../4/" title="파트 4">4</a> |
| 17 | + <span class="separator"> | </span> |
| 18 | + <a href="../5/" title="파트 5">5</a> |
| 19 | + <span class="separator"> | </span> |
| 20 | + <strong>6</strong> |
| 21 | + <span class="separator"> | </span> |
| 22 | + <a href="/en/documentation/faq/7/" title="파트 7">7</a> |
| 23 | + <span class="separator"> | </span> |
| 24 | + <a href="/en/documentation/faq/8/" title="파트 8">8</a> |
| 25 | + <span class="separator"> | </span> |
| 26 | + <a href="/en/documentation/faq/9/" title="파트 9">9</a> |
| 27 | + <span class="separator"> | </span> |
| 28 | + <a href="/en/documentation/faq/10/" title="파트 10">10</a> |
| 29 | + <span class="separator"> | </span> |
| 30 | + <a href="/en/documentation/faq/11/" title="파트 11">11</a> |
| 31 | + </div> |
| 32 | + <h1>공식 Ruby FAQ</h1> |
| 33 | +
|
| 34 | +--- |
| 35 | + |
| 36 | +{% include faq-notice.md %} |
| 37 | + |
| 38 | +## 구문 |
| 39 | + |
| 40 | +### 즉시 값(immediate value)과 참조의 차이점은 무엇인가요? |
| 41 | +{: #immediate} |
| 42 | + |
| 43 | +{% include faq-out-of-date.html %} |
| 44 | + |
| 45 | +`Fixnum`, `true`, `nil`, `false`는 즉시 값으로 구현되어 있습니다. 즉시 |
| 46 | +값을 사용하면 변수는 객체에 대한 참조가 아니라 객체 자체를 보유합니다. |
| 47 | + |
| 48 | +이러한 객체에는 싱글톤 메서드를 정의할 수 없습니다. 동일한 값을 가진 두 개 |
| 49 | +의 `Fixnum`은 항상 동일한 객체 인스턴스를 나타내므로, (예를 들어) 값이 |
| 50 | +`1`인 `Fixnum`에 대한 인스턴스 변수는 시스템의 모든 '1'에 공유됩니다. 따라서 |
| 51 | +이 중 하나에 대해서만 싱글톤 메서드를 정의하는 것은 불가능합니다. |
| 52 | + |
| 53 | +### `nil`과 `false`의 차이점은 무엇인가요? |
| 54 | + |
| 55 | +먼저 유사성부터 설명하겠습니다. `nil`과 `false`는 부울 컨텍스트에서 `false`로 |
| 56 | +평가되는 유일한 두 개의 객체입니다. |
| 57 | +(즉, 이 둘은 유일한 "falsy" 값이며 다른 모든 객체는 "truthy" 입니다.) |
| 58 | + |
| 59 | +그러나 `nil`과 `false`는 서로 다른 클래스(`NilClass`와 `FalseClass`)의 |
| 60 | +인스턴스이며, 다른 곳에서는 다른 동작을 합니다. |
| 61 | + |
| 62 | +술어(predicate) 메서드(이름이 물음표로 끝나는 메서드)는 `true` 또는 `false`를 |
| 63 | +반환하는 것이 좋습니다. 실패를 표시해야 하는 다른 메서드는 `nil`을 반환하는 |
| 64 | +것이 좋습니다. |
| 65 | + |
| 66 | +### 빈 문자열이 `false`가 아닌 이유는 무엇인가요? |
| 67 | + |
| 68 | +Q: 조건 표현식에서 빈 문자열(`""`)이 `true`를 반환하던데요! Perl에서 |
| 69 | +는 `false`였는데... |
| 70 | + |
| 71 | +A: 하지만 Ruby는 Perl이 아닙니다 ;-). Ruby에서는 조건부 컨텍스트에서 |
| 72 | + `nil`과 `false`만 거짓입니다. |
| 73 | + |
| 74 | +`empty?`를 사용하거나 문자열을 `""`와 비교하거나 문자열의 `size`, `length`를 |
| 75 | +`0`과 비교하여 문자열이 비어 있는지 확인할 수 있습니다. |
| 76 | + |
| 77 | +### `:name`은 무엇을 의미하나요? |
| 78 | + |
| 79 | +이름 뒤에 콜론을 붙이면 식별자와 일대일로 대응하는 심볼 객체가 생성됩니다. |
| 80 | +프로그램이 실행되는 동안 주어진 이름이나 문자열에 대해 동일한 심볼 객체가 |
| 81 | +생성됩니다. 심볼은 `"name".intern` 또는 `"name".to_sym`으로 생성할 수도 |
| 82 | +있습니다. |
| 83 | + |
| 84 | +심볼 객체는 메서드, 변수 등에 대한 식별자를 나타낼 수 있습니다. |
| 85 | +`define_method`, `method_missing`, `trace_var`와 같은 일부 메서드에는 심볼이 |
| 86 | +필요합니다. 다른 메서드(예: `attr_accessor`, `send`, `autoload`)는 |
| 87 | +문자열도 허용합니다. |
| 88 | + |
| 89 | +심볼은 한 번만 생성되기 때문에 해시 키로 자주 사용됩니다. 문자열 해시 키는 |
| 90 | +매번 사용할 때마다 새 객체를 생성하므로 약간의 메모리 오버헤드가 발생합니다. |
| 91 | +심볼 해시 키를 위한 특별한 구문도 있습니다. |
| 92 | + |
| 93 | +~~~ |
| 94 | +person_1 = { :name => "John", :age => 42 } |
| 95 | +person_2 = { name: "Jane", age: 24 } # 대안 문법 |
| 96 | +~~~ |
| 97 | + |
| 98 | +심볼을 열거형 값으로 사용하거나 상수에 고유한 값을 할당하는 데에도 사용할 수 |
| 99 | +있습니다. |
| 100 | + |
| 101 | +~~~ |
| 102 | +status = :open # :closed, ... |
| 103 | +
|
| 104 | +NORTH = :NORTH |
| 105 | +SOUTH = :SOUTH |
| 106 | +~~~ |
| 107 | + |
| 108 | +### 심볼의 값에 액세스하려면 어떻게 해야 하나요? |
| 109 | + |
| 110 | +심볼에 해당하는 변수의 값을 얻으려면 `symbol.to_s` 또는 `"#{심볼}"`을 |
| 111 | +사용하여 변수 이름을 얻은 다음 심볼의 범위에서 이를 평가하여 변수의 내용 |
| 112 | +을 얻을 수 있습니다. |
| 113 | + |
| 114 | +~~~ |
| 115 | +a = "This is the content of `a'" |
| 116 | +b = eval("#{:a}") |
| 117 | +a.object_id == b.object_id # => true |
| 118 | +~~~ |
| 119 | + |
| 120 | +다음을 사용할 수도 있습니다. |
| 121 | + |
| 122 | +~~~ |
| 123 | +b = binding.local_variable_get(:a) |
| 124 | +~~~ |
| 125 | + |
| 126 | +심볼이 메서드의 이름인 경우 `send`를 사용할 수 있습니다. |
| 127 | + |
| 128 | +~~~ |
| 129 | +class Demo |
| 130 | + def hello |
| 131 | + "Hello, world" |
| 132 | + end |
| 133 | +end |
| 134 | +
|
| 135 | +demo = Demo.new |
| 136 | +demo.send(:hello) |
| 137 | +~~~ |
| 138 | + |
| 139 | +또는 `Object#method`를 사용하여 해당 `Method` 객체를 반환한 다음 호출할 |
| 140 | +수 있습니다. |
| 141 | + |
| 142 | +~~~ |
| 143 | +m = demo.method(:hello) # => #<Method: Demo#hello> |
| 144 | +m.call # => "Hello, world" |
| 145 | +~~~ |
| 146 | + |
| 147 | +### `loop`는 제어 구조인가요? |
| 148 | + |
| 149 | +`loop`는 제어 구조체처럼 보이지만 실제로는 `Kernel`에 정의된 메서드입니다. |
| 150 | +loop 다음 블록은 지역 변수에 대한 새로운 스코프를 만듭니다. |
| 151 | + |
| 152 | +### Ruby에는 후 테스트(post-test) 루프가 없습니다. |
| 153 | + |
| 154 | +Q: Ruby에는 `do { ... } while` 구문이 없는데 마지막에 조건을 테스트하는 |
| 155 | +루프를 어떻게 구현하나요? |
| 156 | + |
| 157 | +Clemens Hintze의 답변: Ruby의 `begin ... end`와 `while`, `until` 문 |
| 158 | +수정자를 조합하여 동일한 효과를 얻을 수 있습니다. |
| 159 | + |
| 160 | +~~~ |
| 161 | +i = 0 |
| 162 | +begin |
| 163 | + puts "i = #{i}" |
| 164 | + i += 1 |
| 165 | +end until i > 4 |
| 166 | +~~~ |
| 167 | + |
| 168 | +결과: |
| 169 | + |
| 170 | +~~~ |
| 171 | +i = 0 |
| 172 | +i = 1 |
| 173 | +i = 2 |
| 174 | +i = 3 |
| 175 | +i = 4 |
| 176 | +~~~ |
| 177 | + |
| 178 | +### `p {}`의 경우 처럼 해시 리터럴을 메서드에 전달할 수 없는 이유는 무엇인가요? |
| 179 | + |
| 180 | +`{}`는 `Hash` 생성자가 아닌 블록으로 파싱됩니다. `p({})`처럼 매개변수라는 |
| 181 | +사실을 명시하면 `{}`가 표현식으로 처리되도록 할 수 있습니다. |
| 182 | + |
| 183 | +### `def pos=(val)`가 작동하지 않습니다! |
| 184 | + |
| 185 | +다음과 같은 코드가 있지만 `pos = 1` 메서드를 사용할 수 없습니다. |
| 186 | + |
| 187 | +~~~ |
| 188 | +def pos=(val) |
| 189 | + @pos = val |
| 190 | + puts @pos |
| 191 | +end |
| 192 | +~~~ |
| 193 | + |
| 194 | +`=`가 뒤에 붙은 메서드는 명시적 수신자와 함께 호출해야 합니다(수신자 |
| 195 | +가 없으면 지역 변수에 할당하는 것뿐입니다). `self.pos = 1`로 |
| 196 | +호출하세요. |
| 197 | + |
| 198 | +### `'\1'`과 `'\\1'`의 차이점은 무엇인가요? |
| 199 | + |
| 200 | +이들은 동일한 의미를 갖습니다. 작은따옴표로 묶인 문자열에서는 `\'`와 `\\`만 |
| 201 | +변환되고 다른 조합은 변경되지 않습니다. |
| 202 | + |
| 203 | +그러나 큰따옴표로 묶인 문자열에서 `"\1"`은 바이트 `\001`(8진수 |
| 204 | +비트 패턴)이고, `"\\1"`은 백슬래시와 문자 `"1"`이 포함된 두 문자로 된 |
| 205 | +문자열입니다. |
| 206 | + |
| 207 | +### '..`와 '...`의 차이점은 무엇인가요? |
| 208 | + |
| 209 | +'...`는 범위에 오른쪽을 포함하지만 '...`는 포함하지 않습니다. |
| 210 | + |
| 211 | +~~~ |
| 212 | +(5..8).to_a # => [5, 6, 7, 8] |
| 213 | +(5...8).to_a # => [5, 6, 7] |
| 214 | +~~~ |
| 215 | + |
| 216 | +### `or`와 `||`의 차이점은 무엇인가요? |
| 217 | + |
| 218 | +Q: `p(nil || "Hello")`는 `"Hello"`를 출력하지만 `p(nil or "Hello")`는 |
| 219 | + 구문 분석 오류를 발생시킵니다. 왜 그럴까요? |
| 220 | + |
| 221 | +A: `or`의 우선순위가 너무 낮기 때문입니다, `p((nil 또는 "Hello") )`는 |
| 222 | +작동합니다. |
| 223 | + |
| 224 | +`or`의 우선 순위는 `=`보다 낮지만 `||`의 우선 순위는 더 높습니다. |
| 225 | + |
| 226 | +~~~ |
| 227 | +foo = nil || "Hello" # foo = (nil || "Hello") 로 해석 |
| 228 | +foo # => "Hello" |
| 229 | +
|
| 230 | +# 하지만 놀랍게도 |
| 231 | +
|
| 232 | +foo = nil or "Hello" # (foo = nil) or "Hello" 로 해석 |
| 233 | +foo # => nil |
| 234 | +~~~ |
| 235 | + |
| 236 | +`or`(및 유사하게 `and`)은 부울 표현식을 결합하는 데 사용하는 것이 **아니라** |
| 237 | +다음과 같은 제어 흐름에 사용하는 것이 가장 좋습니다. |
| 238 | + |
| 239 | +~~~ |
| 240 | +do_something or raise "some error!" |
| 241 | +~~~ |
| 242 | + |
| 243 | +여기서 `do_something`은 오류가 발생하면 `false` 또는 `nil`을 반환합니다. |
| 244 | + |
| 245 | +### Ruby에도 함수 포인터가 있나요? |
| 246 | + |
| 247 | +`Proc.new`, `proc`, `lambda`에 의해 생성된 `Proc` 객체는 변수에서 참조할 수 |
| 248 | +있으므로 해당 변수는 함수 포인터라고 할 수 있습니다. 또한 특정 객체 인스턴스 |
| 249 | +내의 메서드에 대한 참조는 `object.method`를 사용하여 얻을 수 있습니다. |
| 250 | + |
| 251 | +### `load`와 `require`의 차이점은 무엇인가요? |
| 252 | + |
| 253 | +`load`는 Ruby 프로그램(`*.rb`)을 로드하고 실행합니다. |
| 254 | + |
| 255 | +`require`는 Ruby 프로그램도 로드하지만 바이너리 Ruby 확장 모듈(공유 라이브러리 |
| 256 | +또는 DLL)도 로드합니다. 거기에 더해 `require`는 기능이 두 번 이상 로드되지 |
| 257 | +않도록 합니다. |
| 258 | + |
| 259 | +### Ruby에는 예외 처리가 있나요? |
| 260 | + |
| 261 | +Ruby는 유연한 예외 처리 체계를 지원합니다. |
| 262 | + |
| 263 | +~~~ |
| 264 | +begin |
| 265 | + statements which may raise exceptions |
| 266 | +rescue [exception class names] |
| 267 | + statements when an exception occurred |
| 268 | +rescue [exception class names] |
| 269 | + statements when an exception occurred |
| 270 | +ensure |
| 271 | + statements that will always run |
| 272 | +end |
| 273 | +~~~ |
| 274 | + |
| 275 | +`begin` 절에서 예외가 발생하면 일치하는 예외 이름을 가진 `rescue` 절이 실행 |
| 276 | +됩니다. `ensure`절은 예외 발생 여부에 관계없이 실행됩니다. `rescue` 및 `ensure` |
| 277 | +절은 생략할 수 있습니다. |
| 278 | + |
| 279 | +`rescue` 절에 대해 예외 클래스가 지정되지 않은 경우 묵시적으로 `StandardError` |
| 280 | +예외를 가르키며, `StandardError`와 `is_a?` 관계에 있는 예외가 캡처됩니다. |
| 281 | + |
| 282 | +이 표현식은 `begin` 절의 값을 반환합니다. |
| 283 | + |
| 284 | +가장 최근의 예외는 전역 변수 `$!`에 의해 액세스가 가능합니다(따라서 `$!.type`을 |
| 285 | +사용하여 유형을 확인할 수 있습니다). |
0 commit comments