diff --git a/ko/documentation/faq/1/index.md b/ko/documentation/faq/1/index.md
index b793a3e26b..429e5d4c16 100644
--- a/ko/documentation/faq/1/index.md
+++ b/ko/documentation/faq/1/index.md
@@ -13,7 +13,7 @@ header: |
|
3
|
- 4
+ 4
|
5
|
diff --git a/ko/documentation/faq/2/index.md b/ko/documentation/faq/2/index.md
index 7eae98ab49..87efee44e1 100644
--- a/ko/documentation/faq/2/index.md
+++ b/ko/documentation/faq/2/index.md
@@ -13,7 +13,7 @@ header: |
|
3
|
- 4
+ 4
|
5
|
diff --git a/ko/documentation/faq/3/index.md b/ko/documentation/faq/3/index.md
index 2d1ca13393..a629fb2517 100644
--- a/ko/documentation/faq/3/index.md
+++ b/ko/documentation/faq/3/index.md
@@ -13,7 +13,7 @@ header: |
|
3
|
- 4
+ 4
|
5
|
diff --git a/ko/documentation/faq/4/index.md b/ko/documentation/faq/4/index.md
new file mode 100644
index 0000000000..5c93fad7d7
--- /dev/null
+++ b/ko/documentation/faq/4/index.md
@@ -0,0 +1,421 @@
+---
+layout: page
+title: "공식 Ruby FAQ"
+lang: ko
+
+header: |
+
+
콘텐츠
+
|
+
1
+
|
+
2
+
|
+
3
+
|
+
4
+
|
+
5
+
|
+
6
+
|
+
7
+
|
+
8
+
|
+
9
+
|
+
10
+
|
+
11
+
+ 공식 Ruby FAQ
+
+---
+
+{% include faq-notice.md %}
+
+## 변수, 상수, 인수
+
+### 대입하면 객체의 새 복사본이 생성되나요?
+{: #assignment}
+
+모든 변수와 상수는 어떤 객체를 참조(가리킴)합니다. (초기화되지 않은 지역 변수는
+예외입니다. 이 경우 아무것도 참조하지 않습니다. 사용하면 `NameError` 예외가
+발생합니다) 변수에 대입하거나 상수를 초기화할 때 변수 또는 상수가 참조하는
+객체를 설정합니다.
+
+따라서 대입 자체만으로는 객체의 새 복사본이 생성되지 않습니다.
+
+특수한 경우에 대해 더 자세히 설명해 보겠습니다. `Fixnum`, `NilClass`,
+`TrueClass`, `FalseClass`의 인스턴스는 변수나 상수에 직접 포함되며 참조가 사용되지
+않습니다. 숫자 `42` 또는 상수 `true`를 보유한 변수는 실제로 값을 보유하는
+것이지 참조를 보유하는 것이 아닙니다. 따라서 대입은 물리적으로 이러한
+유형의 객체의 복사본을 생성합니다. 이에 대해서는
+[즉시 객체와 참조 객체](/en/documentation/faq/6/#immediate)에서 자세히 설명합니다.
+
+
+### 지역 변수의 스코프는 무엇인가요?
+
+지역 변수에 대한 새로운 스코프는 (1) 최상위 수준(메인), (2) 클래스(또는 모듈)
+정의, (3) 메서드 정의에 적용됩니다.
+
+~~~
+var = 1 # (1)
+class Demo
+ var = 2 # (2)
+ def method
+ var = 3 # (3)
+ puts "in method: var = #{var}"
+ end
+ puts "in class: var = #{var}"
+end
+puts "at top level: var = #{var}"
+Demo.new.method
+~~~
+
+결과:
+
+~~~
+in class: var = 2
+at top level: var = 1
+in method: var = 3
+~~~
+
+(주의: 클래스 정의는 실행 가능한 코드이므로 클래스가 정의될 때 정의에 포함된
+추적 메시지가 기록됩니다.)
+
+블록(`{ ... }`나 `do ... end`)은 거의 새로운 스코프를 도입합니다 ;-)
+블록 내에서 생성된 지역 변수는 블록 외부에서 액세스할 수 없습니다.
+그러나 블록 내의 지역 변수가 호출자 스코프의 기존 지역 변수와 이름이 같으면
+새 지역 변수가 생성되지 않으며, 이후 블록 외부에서 해당 변수에 액세스할 수 있습니다.
+
+~~~
+a = 0
+1.upto(3) do |i|
+ a += i
+ b = i*i
+end
+a # => 6
+# b is not defined here
+~~~
+
+이는 스레드를 사용할 때 중요해지는데, 각 스레드는 스레드 블록 내의
+지역 변수의 자체 복사본을 받습니다.
+
+~~~
+threads = []
+
+["one", "two"].each do |name|
+ threads << Thread.new do
+ local_name = name
+ a = 0
+ 3.times do |i|
+ Thread.pass
+ a += i
+ puts "#{local_name}: #{a}"
+ end
+ end
+end
+
+threads.each {|t| t.join }
+~~~
+
+다음 결과가 나올 수 있습니다. (스케줄러가 `Thread.pass`에 의해 힌트를 받은 대로
+스레드를 전환하는 경우입니다. 이는 OS 및 프로세서에 따라 달라집니다)
+
+~~~
+one: 0
+two: 0
+one: 1
+two: 1
+one: 3
+two: 3
+~~~
+
+`while`, `until`, `for`는 블록이 아닌 제어 구조이므로 그 안에 있는
+지역 변수는 바깥 환경에서 액세스할 수 있습니다. 그러나 `loop`는 메서드이며
+관련 블록은 새로운 스코프를 도입합니다.
+
+### 지역 변수는 언제 액세스할 수 있나요?
+
+사실 이 질문은 이렇게 묻는 것이 더 나을 수 있습니다. "Ruby는 어느 시점에서
+어떤 것이 변수라는 것을 알아내는가?" 문제는 단순한 표현식 `a`가 변수일 수도
+있고 매개변수가 없는 메서드에 대한 호출일 수도 있기 때문에 발생합니다.
+어떤 경우인지 판단하기 위해 Ruby는 대입문을 찾습니다.
+소스에서 `a`를 사용하기 전 어느 지점에서 `a`가 대입되는 것을 확인하면 `a`를
+변수로 구문 분석하고, 그렇지 않으면 메서드로 처리하기로 결정합니다.
+다소 병적인 사례로 Clemens Hintze가 만든 이 코드 조각을 살펴 보세요.
+
+
+~~~
+def a
+ puts "method `a' called"
+
+ 99
+end
+
+[1, 2].each do |i|
+ if i == 2
+ puts "a = #{a}"
+ else
+ a = 1
+ puts "a = #{a}"
+ end
+end
+~~~
+
+결과:
+
+~~~
+a = 1
+method `a' called
+a = 99
+~~~
+
+구문 분석 중에 Ruby는 첫 번째 `puts` 문에서 `a`가 사용된 것을 보고 `a`에
+대한 할당을 아직 보지 못했기 때문에 메서드 호출이라고 가정합니다. 하지만 두 번째
+`puts` 문에 도달하면 대입이 확인되었으므로 `a`를 변수로 취급합니다.
+
+주의: 대입은 실행될 필요가 없으며 Ruby가 확인만 하면 됩니다. 이 프로그램은 오류를
+발생시키지 않습니다.
+
+~~~
+a = 1 if false; a # => nil
+~~~
+
+변수와 관련된 이 문제는 일반적으로 문제가 되지 않습니다. 이 문제가 발생하면
+변수에 대한 첫 번째 액세스 전에 `a = nil`과 같은 대입을 시도해 보세요. 이렇게
+하면 이후에 루프에 나타나는 지역 변수에 대한 액세스 시간이 빨라지는 추가적인
+이점이 있습니다.
+
+### 상수의 스코프는 무엇인가요?
+
+클래스 또는 모듈 정의에 정의된 상수는 해당 클래스 또는 모듈의 정의 내에서
+직접 액세스할 수 있습니다.
+
+중첩된 클래스 및 모듈 내에서 외부 클래스 및 모듈의 상수에 직접 액세스할
+수 있습니다.
+
+슈퍼클래스와 포함된 모듈의 상수에 직접 액세스할 수도 있습니다.
+
+이러한 경우 외에도 `::` 연산자, `ModuleName::CONST1` 또는 `ClassName::CONST2`를
+사용하여 클래스 및 모듈 상수에 액세스할 수 있습니다.
+
+### 인수는 어떻게 전달되나요?
+
+실제 인수는 메서드가 호출될 때 형식 인수에 대입됩니다.
+(대입의 의미에 대한 자세한 내용은 [대입](#assignment)을 참조하세요.)
+
+~~~
+def add_one(number)
+ number += 1
+end
+
+a = 1
+add_one(a) # => 2
+a # => 1
+~~~
+
+객체 참조를 전달하기 때문에, 메서드가 전달된 변경 가능한 객체의 내용을 수정할 수
+있습니다.
+
+~~~
+def downer(string)
+ string.downcase!
+end
+
+a = "HELLO" # => "HELLO"
+downer(a) # => "hello"
+a # => "hello"
+~~~
+
+다른 언어의 참조에 의한 전달과 다릅니다.
+
+### 형식 인수에 대한 대입이 실제 인수에 영향을 주나요?
+
+형식 인수는 지역 변수입니다. 메서드 내에서 형식 인수에 대입하면 단순히 인수가
+다른 객체를 참조하도록 변경됩니다.
+
+### 형식 인수를 통해 메서드를 호출하면 어떻게 되나요?
+
+모든 Ruby 변수(메서드 인수 포함)는 객체에 대한 참조로 작동합니다. 이러한
+객체에서 메서드를 호출하여 객체의 상태를 가져오거나 변경하고 객체가 어떤 작업을
+수행하도록 할 수 있습니다. 메서드에 전달된 객체로 이 작업을 수행할 수 있습니다.
+이러한 종류의 부작용으로 인해 프로그램을 따라가기 어려울 수 있으므로
+이 작업을 수행할 때 주의해야 합니다.
+
+### 인수 앞에 `*`가 붙으면 무슨 뜻인가요?
+
+별표를 형식 매개변수 목록의 일부로 사용하면 인수를 배열로 모으고 별표가
+표시된 매개변수에 해당 배열을 할당하여 메서드에 임의의 수의 인수를 전달
+할 수 있습니다.
+
+~~~
+def foo(prefix, *all)
+ all.each do |element|
+ puts "#{prefix}#{element}"
+ end
+end
+
+foo("val = ", 1, 2, 3)
+~~~
+
+결과:
+
+~~~
+val = 1
+val = 2
+val = 3
+~~~
+
+메서드 호출에 사용될 때 `*`는 배열을 확장하여 개별 요소를 인수로 전달합니다.
+
+~~~
+a = [1, 2, 3]
+foo(*a)
+~~~
+
+다음의 경우 마지막 인수 앞에 `*`를 붙일 수 있습니다.
+
+1. 다중 대입의 좌항
+2. 다중 대입의 우항
+3. 메서드 형식 인수의 정의
+4. 메서드 호출의 실제 인수
+5. `case` 구조의 `when` 절
+
+
+예시:
+
+~~~
+x, *y = [7, 8, 9]
+x # => 7
+y # => [8, 9]
+x, = [7, 8, 9]
+x # => 7
+x = [7, 8, 9]
+x # => [7, 8, 9]
+~~~
+
+### 인수 앞에 `&`가 붙으면 무슨 뜻인가요?
+
+메서드의 마지막 형식 인자 앞에 앰퍼샌드(`&`)가 붙으면 메서드 호출 뒤에 오는
+블록이 `Proc` 객체로 변환되어 형식 매개변수에 할당됩니다.
+
+메서드 호출의 마지막 실제 인수가 `Proc` 객체인 경우, 이름 앞에 앰퍼샌드를
+붙여 블록으로 변환할 수 있습니다. 그런 다음 메서드는 `yield`를 사용하여 호출할
+수 있습니다.
+
+~~~
+def meth1(&b)
+ puts b.call(9)
+end
+
+meth1 {|i| i + i }
+
+def meth2
+ puts yield(8)
+end
+
+square = proc {|i| i * i }
+
+meth2 {|i| i + i }
+meth2 &square
+~~~
+
+결과:
+
+~~~
+18
+16
+64
+~~~
+
+### 형식 인수의 기본값을 지정하려면 어떻게 해야 하나요?
+
+~~~
+def greet(p1="hello", p2="world")
+ puts "#{p1} #{p2}"
+end
+
+greet
+greet("hi")
+greet("morning", "mom")
+~~~
+
+결과:
+
+~~~
+hello world
+hi world
+morning mom
+~~~
+
+메서드가 호출될 때 기본값(임의의 표현식일 수 있음)이 평가됩니다. 기본값은
+메서드의 스코프를 사용하여 평가됩니다.
+
+### 블록에 인수를 전달하려면 어떻게 하나요?
+
+블록의 형식 매개변수는 블록 시작 부분의 세로 막대 사이에 표시됩니다.
+
+~~~
+proc {|a, b| a <=> b }
+~~~
+
+이러한 매개변수는 실제로 지역 변수입니다. 블록이 실행될 때 같은 이름의 기존
+지역 변수가 존재하면, 블록 호출에 의해 해당 변수가 수정됩니다. 이는 좋을 수도
+나쁠 수도 있습니다.
+
+일반적으로 인수는 `yield`(또는 `yield`를 호출하는 이터레이터)를 사용하거나
+`Proc.call` 메서드를 사용하여 블록에 전달됩니다.
+
+### 내 객체가 예기치 않게 변경된 이유는 무엇인가요?
+
+~~~
+A = a = b = "abc"
+b.concat("d") # => "abcd"
+a # => "abcd"
+A # => "abcd"
+~~~
+
+변수는 객체에 대한 참조를 보유합니다. `A = a = b = "abc"` 할당은 문자열
+`"abc"`에 대한 참조를 `A`, `a`, `b`에 넣습니다.
+
+`b.concat("d")`를 호출하면 해당 객체에 대해 concat 메서드를 호출하여
+`"abc"`에서 `"abcd"`로 변경합니다. `a`와 `A`도 동일한 객체를 참조하기 때문에 겉보기
+값도 변경됩니다.
+
+이는 실제로 발생할 수 있는 문제에 비하면 작은 것입니다.
+
+또한 모든 객체는 동결(frozen)하여 변경되지 않도록 보호할 수 있습니다.
+
+### 상수의 값이 변경되긴 하는 건가요?
+
+상수는 이름이 대문자로 시작하는 변수입니다. 상수는 인스턴스 메서드 내에서
+새로 대입할 수 없지만, 그 외에는 마음대로 변경할 수 있습니다.
+상수에 새 값이 대입되면 경고가 표시됩니다.
+
+### 별도의 파일에서 변수를 로드할 수 없는 이유는 무엇인가요?
+
+`file1.rb`에 다음이 포함되어 있다고 가정합시다.
+
+~~~
+var1 = 99
+~~~
+
+그리고 다른 파일에서 로드합니다.
+
+~~~
+require_relative "file1"
+puts var1
+~~~
+
+결과:
+
+~~~
+prog.rb:2:in `': undefined local variable or method `var1' for main:Object (NameError)
+~~~
+
+`load` 및 `require`는 지역 변수를 별도의 익명 네임스페이스에 저장하도록 정렬하여
+효과적으로 지역 변수를 제거하기 때문에 오류가 발생합니다. 이는 코드가
+오염되지 않도록 보호하기 위한 설계입니다.
diff --git a/ko/documentation/faq/index.md b/ko/documentation/faq/index.md
index d29259860f..273977e48e 100644
--- a/ko/documentation/faq/index.md
+++ b/ko/documentation/faq/index.md
@@ -13,7 +13,7 @@ header: |
|
3
|
- 4
+ 4
|
5
|
@@ -51,8 +51,8 @@ Stollsteimer에게 감사드립니다.
* [일반적인 질문](1/)
* [Ruby의 경쟁 상대는...?](2/)
-* [Ruby 설치하기](/en/documentation/faq/3/)
-* [변수, 상수 및 인수](/en/documentation/faq/4/)
+* [Ruby 설치하기](3/)
+* [변수, 상수, 인수](4/)
* [이터레이터](/en/documentation/faq/5/)
* [구문](/en/documentation/faq/6/)
* [메서드](/en/documentation/faq/7/)