|
| 1 | +--- |
| 2 | +layout: page |
| 3 | +title: "C나 C++에서 Ruby로" |
| 4 | +lang: ko |
| 5 | +--- |
| 6 | + |
| 7 | +Ruby에서 코드가 C 또는 C++와 어떻게 다른지 항목 별로 설명하는 것은 상당히 |
| 8 | +큰 차이가 있기 때문에 어렵습니다. |
| 9 | +이 어려움의 원인 중 하나는 Ruby 런타임이 많은 일을 해 주기 때문입니다. |
| 10 | +Ruby는 C의 "숨겨진 메커니즘 없음" 원칙에서 가능한 한 멀리 있는 것 같습니다. |
| 11 | +Ruby의 요점은 런타임이 더 많은 작업을 수행하는 대신 인간의 작업을 더 쉽게 |
| 12 | +만드는 것입니다. 최적화를 위해 코드를 프로파일링 하지 않는 한, Ruby를 사용할 때 |
| 13 | +"컴파일러를 행복하게 유지"하는 데 조금도 신경을 쓸 필요가 없습니다. |
| 14 | + |
| 15 | +즉, Ruby 코드가 "같은 일을 하는" C 또는 C++ 코드보다 훨씬 느리게 실행될 것으로 |
| 16 | +예상할 수 있습니다. 동시에 Ruby 프로그램을 얼마나 빨리 시작하고 실행할 수 |
| 17 | +있는지, 작성하는 데 몇 줄의 코드가 필요한지 빠르게 이해할 수 있습니다. |
| 18 | +Ruby는 C++ 보다 훨씬 간단합니다. Ruby는 여러분을 응석받이로 만들 것입니다. |
| 19 | + |
| 20 | +Ruby는 정적으로 타입이 결정되지 않고 동적으로 결정됩니다. 런타임은 실행 시간에 |
| 21 | +가능한 한 많은 작업을 수행합니다. 예를 들어, Ruby 프로그램이 "링크"(즉, 로드 및 |
| 22 | +사용)할 모듈이나 미리 호출할 메서드를 알 필요가 없습니다. |
| 23 | + |
| 24 | +다행스럽게도 Ruby와 C는 건강한 공생 관계를 가지고 있습니다. Ruby는 소위 |
| 25 | +"확장 모듈"을 지원합니다. 이들은 Ruby 프로그램에서 사용할 수 있지만(외부에서 볼 |
| 26 | +때 다른 Ruby 모듈처럼 보이고 작동함) C로 작성된 모듈입니다. 이런 식으로 Ruby |
| 27 | +소프트웨어의 성능에 중요한 부분을 구획화하고 순수한 C로 만들 수 있습니다. |
| 28 | + |
| 29 | +물론 Ruby 자체는 C로 작성되었습니다. |
| 30 | + |
| 31 | +### C와 비슷한 점 |
| 32 | + |
| 33 | +C처럼, Ruby에서도... |
| 34 | + |
| 35 | +* 원하는 경우 절차적으로 프로그래밍할 수 있습니다(그러나 내부에서는 여전히 객체 |
| 36 | + 지향일 것입니다). |
| 37 | +* 대부분의 연산자는 동일합니다(복합 할당 및 비트 연산자 포함). 그러나 Ruby에는 |
| 38 | + `++` 또는 `--`가 없습니다. |
| 39 | +* `__FILE__` 및 `__LINE__`이 있습니다. |
| 40 | +* 특별한 `const` 키워드는 없지만 상수도 쓸 수 있습니다. 상수다움은 명명 |
| 41 | + 규칙으로 결정됩니다. 대문자로 시작하는 이름은 상수입니다. |
| 42 | +* 문자열은 큰따옴표로 묶습니다. |
| 43 | +* 문자열은 변경 가능합니다. |
| 44 | +* `man` 페이지와 마찬가지로 `ri` 명령을 사용하여 터미널 창에서 대부분의 문서를 |
| 45 | + 읽을 수 있습니다. |
| 46 | +* 동일한 종류의 커맨드 라인 디버거를 사용할 수 있습니다. |
| 47 | + |
| 48 | +### C++과 비슷한 점 |
| 49 | + |
| 50 | +C++처럼, Ruby에서도... |
| 51 | + |
| 52 | +* 대부분 같은 연산자를 사용합니다(심지어 `::`까지). `<<`는 종종 목록에 요소를 |
| 53 | + 추가하는 데 사용됩니다. 하지만 주의할 것이 하나 있습니다. Ruby에서는 `->`를 |
| 54 | + 사용하지 않습니다. 항상 `.`입니다. |
| 55 | +* `public`, `private` 및 `protected`는 유사한 작업을 수행합니다. |
| 56 | +* 상속 구문은 동일하게 한 문자이지만 `:` 대신 `<`를 사용합니다. |
| 57 | +* C++에서 `namespace`가 사용되는 방식과 유사하게 코드를 "모듈"에 넣을 수 |
| 58 | + 있습니다. |
| 59 | +* 예외도 비슷한 방식으로 작동하지만 순수 예외를 보호하기 위해 키워드 이름이 |
| 60 | + 변경되었습니다. |
| 61 | + |
| 62 | +### C와 다른 점 |
| 63 | + |
| 64 | +C와는 다르게, Ruby에서는... |
| 65 | + |
| 66 | +* 코드를 컴파일할 필요가 없습니다. 직접 실행하면 됩니다. |
| 67 | +* 객체는 강력한 타입입니다(변수 이름 자체에는 타입이 전혀 없음). |
| 68 | +* 매크로나 전처리기가 없습니다. 캐스트가 없습니다. 포인터도 없습니다(포인터 |
| 69 | + 연산도 없습니다). typedefs, sizeof, enum도 없습니다. |
| 70 | +* 헤더 파일이 없습니다. 기본 소스 코드 파일에서 기능(일반적으로 "메서드"라고 |
| 71 | + 함)과 클래스를 정의하기만 하면 됩니다. |
| 72 | +* `#define`이 없습니다. 대신 상수를 사용하십시오. |
| 73 | +* 모든 변수는 힙에 저장됩니다. 또한, 가비지 컬렉터가 처리하므로 직접 해제할 필요가 |
| 74 | + 없습니다. |
| 75 | +* 메서드(예: 함수)에 대한 인수는 값으로 전달되며 값은 항상 개체 참조입니다. |
| 76 | +* `#include <foo>` 또는 `#include "foo"` 대신 `require 'foo'`를 사용합니다. |
| 77 | +* 어셈블리를 사용할 수 없습니다. |
| 78 | +* 줄 끝에 세미콜론이 없습니다. |
| 79 | +* `if` 및 `while` 조건 표현식에는 괄호 없이 사용합니다. |
| 80 | +* 메서드(예: 함수) 호출에 대한 괄호는 종종 생략 가능합니다. |
| 81 | +* 일반적으로 중괄호를 사용하지 않습니다. `end` 키워드로 여러 줄 구성(`while` |
| 82 | + 루프와 같은)을 끝냅니다. |
| 83 | +* `do` 키워드는 소위 "블록"을 위한 것입니다. C와 같은 "do 문"이 없습니다. |
| 84 | +* "블록"이라는 용어는 다른 의미를 가집니다. 실행하는 동안 메서드 본문이 블록을 |
| 85 | + 호출할 수 있도록 메서드 호출과 연결하는 코드 블록용입니다. |
| 86 | +* 변수 선언이 없습니다. 필요할 때 즉시 새 이름을 지정하기만 하면 됩니다. |
| 87 | +* 참 거짓을 확인할 때 `false` 및 `nil`만 거짓 값으로 평가됩니다. 다른 모든 것은 |
| 88 | + true입니다(`0`, `0.0` 및 `"0"` 포함). |
| 89 | +* `char`가 없습니다. 단지 1자로 된 문자열입니다. |
| 90 | +* 문자열은 null 바이트로 끝나지 않습니다. |
| 91 | +* 배열 리터럴은 중괄호 대신 대괄호 안에 들어갑니다. |
| 92 | +* 배열에 더 많은 요소를 넣으면 배열이 자동으로 커집니다. |
| 93 | +* 두 개의 배열을 더하면 포인터 연산을 수행하는 대신 새롭고 더 큰 배열(물론 힙에 |
| 94 | + 할당됨)을 반환합니다. |
| 95 | +* 대부분의 경우 모든 것이 표현식입니다(즉, `while` 문은 실제로 rvalue로 |
| 96 | + 평가됩니다). |
| 97 | + |
| 98 | +### C++과 다른 점 |
| 99 | + |
| 100 | +C과는 다르게, Ruby에서는... |
| 101 | + |
| 102 | +* 명시적인 참조가 없습니다. 즉, Ruby에서 모든 변수는 일부 개체에 대해 자동으로 |
| 103 | + 역참조된 이름일 뿐입니다. |
| 104 | +* 개체는 강 타입이지만 *동적* 타입이 지정됩니다. 런타임은 *실행 시간에* 해당 메서드 |
| 105 | + 호출이 실제로 작동하는지 확인합니다. |
| 106 | +* "constructor"는 클래스 이름 대신 `initialize`라고 합니다. |
| 107 | +* 모든 메서드는 항상 가상입니다. |
| 108 | +* "클래스"(정적) 변수 이름은 항상 `@@`로 시작합니다.(예: `@@total_widgets`) |
| 109 | +* 멤버 변수에 직접 접근하지 않습니다. 공용 멤버 변수(Ruby에서 attributes로 |
| 110 | + 부름)에 대한 모든 액세스는 메서드를 통해 이루어집니다. |
| 111 | +* `this`가 아니라 `self`입니다. |
| 112 | +* 일부 메서드는 '?' 또는 '!'로 끝납니다. 실제로 메서드 이름의 일부입니다. |
| 113 | +* 그 자체로는 다중 상속이 없습니다. Ruby에는 "믹스인"이 있습니다(즉, 모듈의 모든 |
| 114 | + 인스턴스 메서드를 "상속"할 수 있음). |
| 115 | +* 일부 대소문자 규칙이 적용됩니다(예: 클래스 이름은 대문자로 시작하고 변수는 |
| 116 | + 소문자로 시작). |
| 117 | +* 메서드 호출에 대한 괄호는 일반적으로 생략 가능합니다. |
| 118 | +* 언제든지 클래스를 다시 열고 메서드를 더 추가할 수 있습니다. |
| 119 | +* C++ 템플릿이 필요하지 않습니다(주어진 변수에 모든 종류의 개체를 할당할 수 있고 |
| 120 | + 타입은 어쨌든 런타임에 파악되기 때문입니다). 캐스팅도 없습니다. |
| 121 | +* 이터레이션은 약간 다르게 수행됩니다. Ruby에서는 별도의 이터레이터 |
| 122 | + 객체(`vector<T>::const_iterator iter`와 같은)를 사용하지 않습니다. 대신 |
| 123 | + 연속적인 요소를 전달하는 코드 블록을 취하는 컨테이너 개체의 이터레이터 |
| 124 | + 메서드(`each`와 같은)를 사용합니다. |
| 125 | +* 컨테이너 타입은 `Array`와 `Hash` 두 가지뿐입니다. |
| 126 | +* 타입 변환이 없습니다. 그러나 Ruby를 사용하면 필요하지 않다는 것을 알게 될 |
| 127 | + 것입니다. |
| 128 | +* 멀티스레딩은 내장되어 있지만 Ruby 1.8부터는 네이티브 스레드와 달리 "그린 |
| 129 | + 스레드"(인터프리터 내에서만 구현됨)입니다. |
| 130 | +* 단위 테스트 라이브러리는 Ruby와 함께 표준으로 제공됩니다. |
0 commit comments