 |
|
난이도 : 초급 Neal Ford, Application Architect, ThoughtWorks
2005 년 10 월 11 일 Eclipse용 Ruby Development Tools (RDT) 플러그인 사용법을 소개한다. 이 툴을 토대로 Eclipse도 최고의 Ruby 개발 환경이 될 수 있다. Eclipse의 풍부한 인프라를 사용고자 하는 Ruby 개발자와, Ruby에 관심이 있는 자바 개발자들에게 도움이 될 것이다.
왜 Ruby인가?
왜 자존심 강한 자바 개발자가 Ruby를 신경 쓰는가? Ruby는 10년 전 일본에서 만들어진 범용 스크립팅 언어이다. 대중적으로 알려진 것과는 달리 이것은 순수한 객체 지향 언어이다. 자바와는 다르게 Ruby에는 스칼라가 없다. 따라서 정수를 비롯하여 모든 것이 1급 객체이다. Ruby의 신택스는 Smalltalk, Python, Ada에서 많은 부분 빌려왔다. 자바와 마찬가지로 Ruby는 상속 언어이지만 자바 보다 더 나은 기능을 제공한다. (closures와 mix-ins 가 그 예이다.)
Ruby는 현재 인기를 얻어가고 있다. 사람들이 Ruby를 사용하기 시작했다. Ruby는 인터프리디드 언어이고 동적 유형화(dynamic typing)가 적용되기 때문에 런타임 시 모든 종류의 트릭이 가능하다. 동적 유형화와 표출적인 신택스(expressive syntax)로 인해, Ruby에서는 도메인 스팩의 언어를 구현하여 언어의 “미가공” 신택스에서 벗어나 고급 추상화 레벨에서 작업할 수 있다는 점이다. Ruby on Rails 웹 애플리케이션 구현 프레임웍이 바로 그 예가 될 수 있다. Ruby 버전의 Make와 Ant가 하나로 합쳐진 Rake도 마찬가지 예이다.
Ruby를 사용하는 또 다른 이유는 꽤나 냉정한 사람들도 이것을 사용한다는 점이다. 자바가 중요하다고 인식하는 많은 사람들(Glenn Vanderburg, Bruce Tate, Martin Fowler)도 이제는 Ruby를 사용하고 있다. 비록 여러분이 당장 Ruby로 전향할 것은 아니더라도 이 언어에 대해 한번 검토해 볼 시기인 것만은 분명하다.
Ruby를 제한하고 있는 것 중 가장 큰 요소는 좋은 개발 환경이다. RDT가 이 상황을 바꾸었다. Eclipse만큼 Ruby를 실험할 수 있는 좋은 IDE가 또 있을까?
설치
먼저 Ruby 부터 설치한다. 이미 설치되어 있다면 Ruby 인터프리터와 라이브러리, Ruby 개발 환경이 있는지를 확인한다.
Ruby 설치하기
Ruby는 주요 플랫폼에서 사용할 수 있다. 비주류 플랫폼에서도 사용할 수 있다. 사실 리눅스나 Cygwin도 가능하다. 명령어 프롬프트에서 ruby -v를 입력한다.
버전 넘버를 모를 경우, 선택한 플랫폼의 배포판을 확인하도록 한다.
Windows®를 구동 중이라면 옵션은 더 쉽다. Ruby판 SourceForge라 할 수 있는 RubyForge에는 One-Click Ruby Installer라고 하는 프로젝트가 있다. 이것으로 Windows에서 Ruby 환경을 설정한다. (참고자료) 또한 FreeRide 라고 하는 IDE를 비롯하여 다른 많은 툴들도 포함되어 있지만 RDT를 사용하고 있다면 대부분 무시해도 된다.
문서
문서와 기타 참고 자료들은 새로운 언어를 처음 사용할 때 매우 중요하다. Ruby 웹 사이트에서 온라인 Ruby 참고문서를 얻을 수 있지만 대부분 오래 전 것들이다. (현재 버전은 1.8.2인데 그 문서는 Ruby V1.6 시절에 작성된 것이다.) 문제는 업데이트된 문서들은 아직 번역이 안되었다. 다행히 Ruby-doc.org에 최신 문서가 있다. API 문서(일종의 Javadoc)와 튜토리얼 및 책이 있다. (참고자료)
Ruby 개발이 시급한 문제라면 Programming Ruby: The Pragmatic Programmer's Guide,(Dave Thomas와 Andy Hunt)(참고자료)를 참조하기 바란다. Ruby에 대한 소개와 Ruby 라이브러리 요건 등이 설명되어 있다. 아울러 Agile Development with Ruby on Rails(Dave Thomas)도 도움이 될 것이다.
RDT 설치
이제 여러분의 컴퓨터에 작동하는 문서화된 버전의 Ruby를 설치했으니 RDT가 필요하다. (참고자료). 여러분에게 익숙한 코드 편집 기능이 많다. RDT는 표준 Eclipse 플러그인이기 때문에 zip 파일을 직접 Eclipse 폴더로 확장할 수 있다.
이제 Ruby 프로젝트를 구현할 준비가 되었다. (그림 1)
그림 1. 새로운 Ruby 프로젝트 구현
Ruby는 자바 보다 이름과 디렉토리 구조에 대한 요건이 훨씬 덜 엄격하다. Ruby에 프로젝트를 구현하는 것은 단순히 디렉토리와 .project 파일을 만드는 것이다. (Ruby에는 클래스경로(classpath)가 없기 때문에 .classpath 파일이 필요 없다.) 또 한가지 자바와 다른 점은 Ruby 프로젝트 위자드는 명확한 src와 bin 디렉토리를 만들지 않는다는 점이다. Ruby는 인터프리티드 언어이기 때문에 아웃풋 폴더가 없다. 작은 프로젝트를 갖고 있다면 Ruby 소스 파일을 프로젝트 파일과 같은 폴더에 둘 수 있다. 또는 디렉토리 계층을 만든다.
Ruby 소스 파일이 필요하다. Ruby 소스 파일을 구현하는 지정된 위자드가 없다. Ruby 소스 파일은 자바에 비해 구조에 대한 요건이 까다롭지 않기 때문에 Ruby 파일을 만들려면 프로젝트의 오른쪽 클릭 메뉴를 사용하여 새로운 파일을 만들면 된다.
그림 2. Ruby 소스 파일 만들기
파일에 표준 확장자 .rb를 반드시 추가하라. Ruby 파일을 만들려면 Ruby perspective를 연다.
그림 3. Ruby 소스 파일을 만드는 Ruby perspective
Ruby perspective는 자바 perspective에서 제공하는 것과 비슷한 아웃라인 뷰의 기능도 한다. 자바와 마찬가지로 Ruby 소스 파일의 엘리먼트들을 검색할 수 있다. raise_salary_by 메소드는 아웃라인과 소스 뷰에 있다. (그림 4)
그림 4. 아웃라인 뷰로 소스 파일 검색하기
다른 고급 플러그인과 마찬가지로 RDT 역시 Window > Preferences 다이얼로그에 커스터마이징 기능을 추가했다. (그림 5)
그림 5. RDT의 커스터마이징 기능
선택사항(preference) 메뉴 아이템으로 신택스 하이라이팅, 포맷팅(Ruby 표준은 두 개의 공간이다.), 신택스 하이라이팅을 변경할 수 있다. 또한 에디터 템플릿을 커스터마이징 할 수 있고 인터프리터를 선택할 수 있다.
RDT 에디터
자바로 인해 우리는 고급 에디터 기능에 이미 익숙해졌기 때문에 그러한 기능을 지원하지 않는 다른 환경으로 옮기기 힘들다. Ruby IDE에 부족한 기능 중 하나가 Content Assist이다. RDT 에디터는 Ruby 코드를 위한 Content Assist를 갖추었다.
그림 6. Content Assist가 지원되는 RDT 에디터
RDT 에디터의 Content Assist는 자바 보다 덜 구체적이다. Ruby에서는 유형(type)을 변수 또는 메소드 리턴에 할당할 수 없다. 식별자로 런타임 시 유형을 결정한다. 강력한 유형화(strongly typed) 언어에 익숙한 사람들에게는 이상하게 보이지만 이 약결합 방식(loose-type coupling)때문에 Ruby가 보다 강력한 기능을 실행할 수 있는 것이다. 예를 들어, 존재하지 않는 메소드를 호출할 경우 실행되는 예외 핸들러를 작성할 수 있다. 이 예외 핸들러는 메소드를 합성하고 이를 호출하기 위해 변경된다. 그와 같은 메타 프로그래밍은 엄밀하게 유형화된 언어에는 적용하기 힘들다.
Content Assist의 뛰어난 기능 중 하나는 Ruby가 식별자로 사용하는 특별한 네이밍 규칙이다. 예를 들어, Ruby에서 모든 멤버 변수들은 처음 사용시 나타나고, 모두 이름의 맨 앞에 @ 부호를 붙여 구별된다. Content Assist를 사용하여 멤버 변수를 찾으려면 @을 먼저 타이핑하고 멤버 변수를 찾도록 한다.
그림 7. Ruby Content Assist의 네이밍 규칙
하지만 동적 유형화(dynamic typing)는 Ruby에서 컨텍스트-민감도에 방해가 된다. 그림 7에서 유일한 합법적인 멤버 변수는 메소드 선언 위에 나타나는 것들이다. 주로 @name, @salary, @hire_year 이다. Content Assist가 선택하는 다른 멤버 변수들은 다른 클래스에서 온 것들이다. RDT 에디터는 문법의 정확성을 구별할 정도는 아니다.
실행 및 디버깅
IDE의 핵심 기능 중 하나는 같은 환경에서 구현한 애플리케이션들을 실행 및 디버깅 할 수 있다는 점이다. RDT는 이 두 가지 모두 가능하다.
인터프리터 지정
Ruby는 인터프리티드(interpreted) 언어이기 때문에 RDT가 애플리케이션을 실행 및 디버깅 하기 전에 인터프리터를 환경과 제휴해야 한다. Windows > Preferences 다이얼로그에 Ruby의 Installed Interpreters 엔트리에서 지정한다.
그림 8. Ruby 인터프리터와 환경 제휴
"Location"텍스트 필드를 bin 디렉토리로 선택한다. RDT는 필요한 나머지 정보를 선택한다. 인터프리터와 제휴하면 애플리케이션을 실행할 준비가 다 된 것이다.
Ruby 애플리케이션 실행
Ruby 애플리케이션을 실행하는 것은 자바 애플리케이션을 실행하는 것과 동일하다. Run 메뉴를 사용하여 Run 설정을 만든다.
그림 9. RDT에서의 Run 설정
애플리케이션을 실행하면 RDT는 Eclipse 워크스페이스 밑에 있는 콘솔 윈도우에서 애플리케이션을 실행한다.
그림 10. RDT내에서 Ruby 애플리케이션 실행
이 예제에서는 콘솔 애플리케이션만 실행하지만 다른 애플리케이션(그래픽 애플리케이션)도 마찬가지이다.
RDT를 이용한 디버깅
IDE의 가장 중요한 기능 중 하나는 애플리케이션을 효과적으로 디버깅하는 것이다. Ruby 인터프리터에는 명령행 디버거가 포함되어 있지만, 그래픽 시대에 누가 명령행 디버거를 사용하겠는가? 다행히도 Ruby 인터프리터는 특정(설정 가능한) 포트를 통해 디버깅 정보를 방송하고 RDT 같은 툴은 그 포트를 통해 리스닝 할 수 있고 개발자가 기대하는 디버깅 지원을 제공한다.
RDT에서 Ruby 애플리케이션을 디버깅 하려면 위 Run 설정 처럼 Debug 설정이 필요하다. 왼쪽 부분에 있는 거터를 클릭하여 중단점을 설정하고 디버거를 설치한다. 자바와 마찬가지로 IDE는 Debug perspective를 변환할 것인지의 여부를 물을 것이다.
그림 11. RDT에서 루비 애플리케이션 디버깅
자바의 디버깅과 비슷하다. 왼쪽 상단 패인은 현재 실행 쓰레드를 보여주고 있다. 오른쪽 상단 패인은 변수 값을 나타낸다. 자바와 마찬가지로 객체를 사용하여 멤버 변수 값을 본다. 왼쪽 중간 패인은 실행 애플리케이션의 소스 코드이고, 오른쪽 중간 패인은 아웃라인 뷰를 보여준다. 여기에서는 에디터로 작동한다. Debug 윈도우 밑 부분에서는 Ruby 인터프리터가 1098 포트에 디버깅 정보를 방송하는 것과 RDT가 그 디버깅 정보용 포트를 리스닝하고 있다는 것을 보여준다.
디버깅 지원은 RDT의 핵심 기능이다. 뛰어난 Ruby 지원을 가진 에디터가 있더라도 명령행 디버거에 의존하여 애플리케이션을 디버깅해야 할 것이다. 완벽한 기능을 갖춘 디버거로 생산성을 높일 수 있다.
테스팅
Ruby에서 자바 개발자들이 가장 어려워하는 것 중 하나가 다이나믹 타이핑이다. 강유형 언어에 익숙하다면 다이나믹 타이핑은 혼돈스럽다. 동적 유형화는 강유형 언어에서는 어렵거나 불가능한 모든 종류의 고급 메타 프로그래밍 트릭이 가능하다. 물론 안정성은 포기해야 한다. 이 두 개에서 장점들만 모을 수는 없을까?
단위 테스팅은 언어들에게는 필수적이지만 Ruby 같은 강유형 언어에는 특히 더 중요하다. 단위 테스팅은 단순한 컴파일 그 이상이다. 사실, 단위 테스팅과 컴파일과의 관계에 대한 시각을 바꿔야 한다. 최근 No Fluff, Just Stuff Software Symposium에서 Stuart Halloway는 다음과 같이 말했다. " 5년 안에, 컴파일은 단위 테스트 중 가장 낮은 범주로 간주될 것이다. " 단위 테스팅은 코드가 의도한 대로 수행하고 있는지를 확인하는 것이다. 단순한 스펠체크가 아니다.
Ruby에서 단위 테스트가 중요하기 때문에 RDT는 단위 테스트 실행을 많이 지원한다. 단위 테스팅은 Ruby에 포함되어 있기 때문에 추가 확장을 다운로드 할 필요가 없다. Ruby 라이브러리에는 TestCase 클래스와 TestSuite 개념이 포함된다. 자신만의 단위 테스트를 구현하여 Test::Unit::TestCase에서 테스트를 분류한다. Listing 1은 Employee클래스 예제이다.
Listing 1. Employee 클래스
class Employee
def initialize(name, salary, hire_year)
@name = name
@salary = salary
@hire_year = hire_year
end
attr_reader :name, :salary, :hire_year
def raise_salary_by(perc)
@salary += (@salary * (perc * 0.01))
end
def to_s
"Name is #{@name}, salary is #{@salary}, " +
"hire year is #{@hire_year}"
end
end
|
이에 상응하는 단위 테스트는 다음과 같다.
Listing 2. Employee클래스용 단위 테스트
require 'test/unit/testcase'
require 'test/unit/autorunner'
require 'hr'
class TestEmployee < Test::Unit::TestCase
@@Test_Salary = 2500
def setup
@emp = Employee.new("Homer", @@Test_Salary, 2003)
end
def test_raise_salary
@emp.raise_salary_by(10)
expected = (@@Test_Salary * 0.10) + @@Test_Salary
assert( expected == @emp.salary)
end
end
|
단위 테스트를 실행하려면 단위 테스트 클래스용 Run 설정을 Test::Unit 유형으로 구현한다.
그림 12. RDT에는 Test::Unit 설정이 포함된다.

이 테스트를 실행하면 자바 단위 테스트와 같은 지원 엘리먼트를 얻게 된다. 왼쪽 아래 코너에 JUnit 같은 패인이 포함된다.
그림 13. IDE에서의 단위 테스트 실행 예제
Ruby에 TestSuites를 구현할 수도 있다. TestSuites는 TestSuite를 리턴하는 수트(suite) 메소드를 정의하는 Ruby 클래스이다. TestSuite는 TestCases 에서 자동으로 정의된 수트들로 구성된다. Listing 3은 TestSuite 샘플이다.
Listing 3. TestSuite 샘플
require 'test/unit/testsuite'
require 'test/unit/ui/tk/testrunner'
require 'test/unit/ui/console/testrunner'
require 'TestEmployee'
require 'TestManager'
class TestSuite_AllTests
def self.suite
suite = Test::Unit::TestSuite.new("HR Tests")
suite << TestEmployee.suite
suite << TestManager.suite
return suite
end
end
#Test::Unit::UI::Tk::TestRunner.run(TestSuite_AllTests)
Test::Unit::UI::Console::TestRunner.run(TestSuite_AllTests)
|
하나의 TestCase 를 실행하는 이전 예제와는 달리 이 수트는 독립 애플리케이션으로서 실행한다. Ruby에는 TestSuite 의 결과를 보여주는 두 가지 방식이 있다. 첫 번째는 Console Test Runner인데 결과를 콘솔에서 보여준다. 두 번째 방식인 Tk TestRunner는 익숙한 다이얼로그를 만들어서 테스트 결과를 보여준다. 그림 14는 Tk TestRunner 다이얼로그 모습이다.
그림 14. TestSuite 다이얼로그
차기 버전 예고
현재 RDT 버전은 0.50이다. 개발자들은 0.60을 위해 열심히 뛰고 있다. 다음 버전에는 더욱 많은 개선이 이루어질 것이다.
- Code folding -- 클래스와 메소드에 대해 코드 폴딩이 가능하다.
- Outline view -- 로컬 변수의 지원으로 보다 자세해 진다.
- RI view -- RDT 뷰에서 Ruby의 ri 유틸리티를 사용한다.
- Task tags -- Ruby 주석에 설정 가능한 키워드(TODO, FIXME)용 태스크를 만든다.
- Editor improvements -- 중괄호, 괄호, 싱글/더블 쿼트의 지동 완성기능 및 코드 보조.
- Inspection shortcuts -- Debug 세션 동안 인스펙션에 자주 사용되는 설정 지름길. 객체의 모든 메소드, 글로벌 상수 등을 모두 보여주는 것이 그 예이다.
다음 버전에서는 JRuby 바이트 코드 컴파일러를 더욱 활용할 예정이다. JRuby는 Ruby 코드가 자바 바이트 코드로 컴파일 되도록 하는 프로젝트이다. 차기 RDT 버전은 Eclipse와의 결합이 보다 더 쉬워진다는 의미가 된다.
요약
Pragmatic Programmer: From Journeyman to Master에서는 매년 새로운 프로그래밍 언어를 배워 시대에 뒤떨어지지 않도록 할 것을 조언하고 있다. Ruby on Rails 프로젝트의 성공에 힘입어 Ruby는 대중성을 획득하였다. 이제는 여러분의 툴 박스에 Ruby도 갖춰놓아야 할 때이다.
참고자료 교육
제품 및 기술 얻기
토론
필자소개  | 
|  | Neal Ford: 애플리케이션 아키텍트, ThoughtWorks |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|