Ruby에서 코드가 C 또는 C++와 어떻게 다른지 항목별로 설명하는 것은 상당히 큰 차이가 있기 때문에 어렵습니다. 이 어려움의 원인 중 하나는 Ruby 런타임이 많은 일을 해 주기 때문입니다. Ruby는 C의 “숨겨진 메커니즘 없음” 원칙에서 가능한 한 멀리 있는 것 같습니다. Ruby의 요점은 런타임이 더 많은 작업을 수행하는 대신 인간의 작업을 더 쉽게 만드는 것입니다. 최적화를 위해 코드를 프로파일링 하지 않는 한, Ruby를 사용할 때 “컴파일러를 행복하게 유지”하는 데 조금도 신경을 쓸 필요가 없습니다.
즉, Ruby 코드가 “같은 일을 하는” C 또는 C++ 코드보다 훨씬 느리게 실행될 것으로 예상할 수 있습니다. 동시에 Ruby 프로그램을 얼마나 빨리 시작하고 실행할 수 있는지, 작성하는 데 몇 줄의 코드가 필요한지 빠르게 이해할 수 있습니다. Ruby는 C++보다 훨씬 간단합니다. Ruby는 여러분을 응석받이로 만들 것입니다.
Ruby는 정적으로 타입이 결정되지 않고 동적으로 결정됩니다. 런타임은 실행 시간에 가능한 한 많은 작업을 수행합니다. 예를 들어, Ruby 프로그램이 “링크”(즉, 로드 및 사용)할 모듈이나 미리 호출할 메서드를 알 필요가 없습니다.
다행스럽게도 Ruby와 C는 건강한 공생 관계를 가지고 있습니다. Ruby는 소위 “확장 모듈”을 지원합니다. 이들은 Ruby 프로그램에서 사용할 수 있지만(외부에서 볼 때 다른 Ruby 모듈처럼 보이고 작동함) C로 작성된 모듈입니다. 이런 식으로 Ruby 소프트웨어의 성능에 중요한 부분을 구획화하고 순수한 C로 만들 수 있습니다.
물론 Ruby 자체는 C로 작성되었습니다.
C와 비슷한 점
C처럼, Ruby에서도…
- 원하는 경우 절차적으로 프로그래밍할 수 있습니다(그러나 내부에서는 여전히 객체 지향일 것입니다).
- 대부분의 연산자는 동일합니다(복합 할당 및 비트 연산자 포함). 그러나 Ruby에는
++
또는--
가 없습니다. __FILE__
및__LINE__
이 있습니다.- 특별한
const
키워드는 없지만 상수도 쓸 수 있습니다. 상수인지 아닌지는 명명 규칙으로 결정됩니다. 대문자로 시작하는 이름은 상수입니다. - 문자열은 큰따옴표로 묶습니다.
- 문자열은 변경 가능합니다.
man
페이지와 마찬가지로ri
명령을 사용하여 터미널 창에서 대부분의 문서를 읽을 수 있습니다.- 동일한 종류의 커맨드 라인 디버거를 사용할 수 있습니다.
C++와 비슷한 점
C++처럼, Ruby에서도…
- 대부분 같은 연산자를 사용합니다(심지어
::
까지).<<
는 종종 배열에 요소를 추가하는 데 사용됩니다. 하지만 주의할 것이 하나 있습니다. Ruby에서는->
를 사용하지 않습니다. 항상.
입니다. public
,private
,protected
는 유사한 작업을 수행합니다.- 상속 구문은 동일하게 한 문자이지만
:
대신<
를 사용합니다. - C++에서
namespace
가 사용되는 방식과 유사하게 코드를 “모듈”에 넣을 수 있습니다. - 예외도 비슷한 방식으로 작동하지만 순수 예외를 보호하기 위해 키워드 이름이 변경되었습니다.
C와 다른 점
C와는 다르게, Ruby에서는…
- 코드를 컴파일할 필요가 없습니다. 직접 실행하면 됩니다.
- 객체는 강 타입입니다(변수 이름 자체에는 타입이 전혀 없음).
- 매크로나 전처리기가 없습니다. 캐스팅이 없습니다. 포인터도 없습니다(포인터 연산도 없습니다). typedef, sizeof, enum도 없습니다.
- 헤더 파일이 없습니다. 메인 소스 코드 파일에서 함수(일반적으로 “메서드”라고 함)와 클래스를 정의하기만 하면 됩니다.
#define
이 없습니다. 대신 상수를 사용하세요.- 모든 변수는 힙에 저장됩니다. 또한, 가비지 컬렉터가 처리하므로 직접 해제할 필요가 없습니다.
- 메서드(예: 함수)에 대한 인수는 값으로 전달되며 그 값은 항상 객체 참조입니다.
#include <foo>
또는#include "foo"
대신require 'foo'
를 사용합니다.- 어셈블리를 사용할 수 없습니다.
- 줄 끝에 세미콜론이 없습니다.
if
및while
조건 표현식을 괄호 없이 적습니다.- 메서드(예: 함수) 호출에 대한 괄호는 종종 생략 가능합니다.
- 일반적으로 중괄호를 사용하지 않습니다.
end
키워드로 여러 줄 구성(while
루프 등)을 끝냅니다. do
키워드는 소위 “블록”을 위한 것입니다. C와 같은 “do 문”이 없습니다.- “블록”이라는 용어는 다른 의미를 가집니다. 실행하는 동안 메서드 본문이 블록을 호출할 수 있도록 메서드 호출과 연결하는 코드 블록을 가리킵니다.
- 변수 선언이 없습니다. 필요할 때 즉시 새 이름을 지정하기만 하면 됩니다.
- 참 거짓을 확인할 때
false
및nil
만 거짓 값으로 평가됩니다. 다른 모든 것은 참입니다(0
,0.0
,"0"
포함). char
가 없습니다. 단지 한 글자로 된 문자열입니다.- 문자열은 null 바이트로 끝나지 않습니다.
- 배열 리터럴은 중괄호 대신 대괄호 안에 들어갑니다.
- 배열에 더 많은 요소를 넣으면 배열이 자동으로 커집니다.
- 두 개의 배열을 더하면 포인터 연산을 수행하는 대신 새롭고 더 큰 배열(물론 힙에 할당됨)을 반환합니다.
- 대부분의 경우 모든 것이 표현식입니다(즉,
while
문은 실제로 rvalue로 평가됩니다).
C++와 다른 점
C++와는 다르게, Ruby에서는…
- 명시적인 참조가 없습니다. 즉, Ruby에서 모든 변수는 일부 객체에 대해 자동으로 역참조된 이름일 뿐입니다.
- 객체는 강 타입이지만 동적 타입이 지정됩니다. 런타임은 실행 시간에 해당 메서드 호출이 실제로 작동하는지 확인합니다.
- “생성자”는 클래스 이름 대신
initialize
라고 합니다. - 모든 메서드는 항상 가상입니다.
- “클래스”(정적) 변수 이름은 항상
@@
로 시작합니다(예:@@total_widgets
). - 멤버 변수에 직접 접근하지 않습니다. 공용 멤버 변수(Ruby에서 attributes로 부름)에 대한 모든 액세스는 메서드를 통해 이루어집니다.
this
가 아니라self
입니다.- 일부 메서드는 ‘?’ 또는 ‘!’로 끝납니다. 실제로 메서드 이름의 일부분입니다.
- 그 자체로는 다중 상속이 없습니다. Ruby에는 “믹스인”이 있습니다(즉, 모듈의 모든 인스턴스 메서드를 “상속”할 수 있음).
- 일부 대소문자 규칙이 적용됩니다(예: 클래스 이름은 대문자로 시작하고 변수는 소문자로 시작).
- 메서드 호출에 대한 괄호는 일반적으로 생략 가능합니다.
- 언제든지 클래스를 다시 열고 메서드를 더 추가할 수 있습니다.
- C++ 템플릿이 필요하지 않습니다(주어진 변수에 모든 종류의 객체를 할당할 수 있고 타입은 어쨌든 런타임에 파악되기 때문입니다). 캐스팅도 없습니다.
- 이터레이션은 약간 다르게 수행됩니다. Ruby에서는 별도의 이터레이터
객체(
vector<T>::const_iterator iter
등)를 사용하지 않습니다. 대신 연속적인 요소를 전달하는 코드 블록을 취하는 컨테이너 객체의 이터레이터 메서드(each
등)를 사용합니다. - 컨테이너 타입은
Array
와Hash
두 가지뿐입니다. - 타입 변환이 없습니다. 그러나 Ruby를 사용하면 필요하지 않다는 것을 알게 될 것입니다.
- 멀티스레딩은 내장되어 있지만 Ruby 1.8부터는 네이티브 스레드와 달리 “그린 스레드”(인터프리터 내에서만 구현됨)입니다.
- 단위 테스트 라이브러리는 Ruby와 함께 표준으로 제공됩니다.