SqueakByExample:6.3
몬티첼로(Monticello)
2.9장 에서 스퀵의 패키징 도구인 몬티첼로에 대해 간단하게 알아봤습니다. 하지만, 몬티첼로에는 알려드린 내용보다 더 많은 기능이 있습니다. 이는 몬티첼로가 패키지를 관리하기 때문입니다. 그렇지만 이 장 에서는 몬티첼로에 관해 말씀드리기 전에 알아야할 중요한 내용인, 패키지는 정확히 무엇인지 부터 설명하도록 하겠습니다.
패키지:스퀵 코드의 선언적 분류(declarative categorization)
패키지 시스템은 단순하며, 스몰토크 소스 코드의 체계를 구성하는 가볍고 간략한 방법입니다. 패키지 시스템은 덧붙여 6.2장 에서 살펴본 오래된 작명관례 라고 불리는 방법을 사용합니다..
예를 들어 설명해 보겠습니다. 스퀵에서 관계형 데이터 베이스를 사용하기위해 개발하고 있는 프레임 워크의 이름을 짓는다고 가정해 봅시다. 만들어지는 프레임워크를 SqueakLink라고 부르고, SqueakLink 프레임워크에 작성된 모든 클래스들을 포함하는 일련의 시스템 카테고리를 만들어 보겠습니다.
Category 'SqueakLink-Connections' contains OracleConnection MySQLConnection PostgresConnection
Category 'SqueakLink-Model' contains DBTable DBRow DBQuery
위에서 보이는것처럼 여러개의 카테고리와 클래스등등이 만들어지겠죠. 하지만 저 클래스들 모두에 일일히 코드를 넣어줘야 하는건 아닙니다. 예를 들자면, SQL 친화적인 상태로 오브젝트를 변환해주는 메소드 등이 있을 수 있습니다..
Object>>asSQL
String>>asSQL
Date>>asSQL
위의 메서드들은 SqueakLink-Connections 카테고리와 SqueakLink-Model 카테고리에 소속되게 됩니다. 하지만 분명한건 당신이 만들게 되는 모든 패키지에 Object 클래스가 소속되어 있는건 아니라는겁니다. 그렇기 때문에 클래스가 다른 패키지에 있는경우 패키지에 특정 메소드를 밀어넣는 방법이 필요한겁니다.
패키지에 다른 클래스의 메소드를 추가하는 작업을 한다면, *squeaklink로 이름지어진(초기 별표와 소문자 이름에 주의합니다) 프로토콜에 다른 객체(Object, String, Date 클래스등)의 메소드를 배치하는 작업을 해야합니다. SqueakLink 라는 패키지명은 SqueakLink-... 카테고리와 *squeaklink 프로토콜의 조합으로 만들어졌습니다. 좀 더 정확히 보자면 패키지에 대한 이름규칙은 다음과 같습니다.
Foo 패키지 이름은 아래의 규칙이 포함됩니다.:
- Foo 카테고리에 소속되어 정의된 모든 클래스, 또는 카테고리 안에서 Foo- 라는 이름으로 시작하는 클래스.
- *foo 라는 이름의 프로토콜로 메소드를 정의하고 분류한 모든 클래스, 또는 *foo- 로 시작되는 모든 이름(이 경우 이름을 비교할때 대소문자는 무시됩니다)
- Foo 카테고리 안의 클래스의 모든 메서드, 또는 카테고리 안에서 Foo- 로 시작되는 모든 이름. *로 시작되는 이름의 프로토콜에 속한 메서드는 제외.
이런 규칙들때문에, 각 클래스 정의와 각 메소스들의 정의는 정확히 하나의 패키지에 속하게 됩니다. 마지막 규칙의 *에 대한 예외는 반드시 적용되어야 하며, 그렇게 해야 해당되는 메서드들이 반드시 다른 패키지에 소속될 수 있기 때문입니다. 두번째 규칙 에서 대소문자 구별을 무시하는 이유는, 관례적으로 카테고리 이름들이 CamelCase(그리고 Space문자를 포함하지 않음)를 사용하는 반면, 프로토콜 이름들은 (Space문자를 포함할 수 있음) 모두 소문자 이기 때문입니다.
PackageInfo 클래스는 이런 규칙들을 적용하며, PackageInfo 클래스로 실행해서 규칙들에 대한 감을 익힐 수 있습니다.
이 작업을 당신의 이미지에 적용하려면, PackageInfo 클래스와 RefactoringBrowser가 이미지에 포함되어야 합니다.
리팩토링 브라우저 코드(the refactoring browser code)는 패키지의 이름으로서, RefactoringEngine 과 함께 패키지 작명 관례(package naming convetions)를 사용합니다. 워크스페이스에서, 아래의 구문으로 패키지의 모델을 만들어봅시다.
refactory := PackageInfo named: 'RefactoringEngine'.
이제 refactory 를 이용해서 패키지를 자세히 살펴보는(introspect) 작업이 가능해졌습니다. 예를 들면, refactory 클래스는 리팩토링 엔진(Refactoring Engine)과 리팩토링 브라우저(Refactoring Browser)를 만드는 긴 클래스의 목록을 반환할 것입니다. refactory coreMethods 는 그 클래스들에 있는 모든 메서드들을 위한 MethodReferences 목록을 반환할 것입니다. refactoryextensionMethods 는 아마도, 가장 흥미로운 질의중 하나일겁니다: refactoryextensionMethods는 RefactoringEngine에 포함되었지만 RefactoringEngine 클래스 내부에는 포함되지 않은, 모든 메서드들의 목록을 반환합니다. 예를 들어, 이 메서드들의 목록은 ClassDescription>>chooseThisClassInstVarThenDo: and SharedPool class>>keys 를 포함합니다.
패키지 기능은 스퀵에 비교적 새롭게 추가된것이지만, 패키지 작명 관례(the package naming convettions)는 이미 사용되던 규칙을 기반으로 하기 때문에, 명확하지 않은 오래된 코드의 분석작업에 PackageInfo 를 사용할 수 있습니다.
(PackageInfo named: 'Collections') externalSubclasses를 분석합니다, 이 표현식은 Collections 패키지에 없는 Collection 의 모든 하위클래스들의 목록을 답으로 내놓을 것입니다.
또한 전체 패키지의 변경 세트(change set)를 얻기 위해 PackageInfo의 인스턴스에 fileout 을 전송할 수 있습니다. 패키지들의 좀더 세련된 버전화를 위해, 우리는 몬티첼로(Monticello)를 사용합니다.
몬티첼로 기본사항(Basic Monticello)
몬티첼로는 미국의 3 번째 대통령 토머스 제퍼슨의 산 꼭대기 집과(the mountaintop home)과 종교의 자유를 위한 버지니아의 법령의 저자의 이름을 본 딴 것입니다. 몬티첼로는 이탈리아어로 "작은 산" 을 의미하고, 항상 이탈리어로 "c" 로 발음되며, 이 음절은 chiair:Mont-y’-che-llo 에서 "ch" 와 같습니다.
그림 6.12에서 볼 수 있듯이, 몬티첼로 브라우저를 열면, 두 개의 목록 패널들을 볼 수 있으며, 나열된 버튼들을 볼 수 있습니다. 왼쪽의 패널은 현재 실행하고 있는 이미지에 로드된 모든 패키지의 목록이며 패키지의 특별한 버전은 이름 뒤에 있는 괄호에서 확인할 수 있습니다.
오른쪽의 패널은 몬티첼로가 알고 있는 모든 소스코드 저장소들의 목록이며, 그 이유는 대개, 해당되는 저장소들로부터 코드를 로드했기 때문입니다. 만약 왼쪽 패널에서 패키지를 선택한다면, 오른쪽 패널은 필터링을 거쳐 선택된 패키지의 버전을 포함하고 있는 저장소들만 보여줍니다.
저장소목록중 package-cache 라는 특정 이름의 디렉토리는, 현재 이미지가 실행중인 디렉토리의 하위 디렉토리입니다. 원격 저장소(remote repository)로부터 코드를 로드 하거나 작성할 때, 복사본이 패키지 캐쉬에 저장되며, 만약 네트워크가 사용 가능하지 않을 때나 패키지에 접근할 필요가 있을때 유용합니다. 그리고, 만약 이메일 첨부파일로 직접 몬티첼로(.mcz) 파일을 받으셨다면, 다운받은 파일을 사용할때 접근하기 위한 가장 편리한 방법은 package-cache 디렉토리에 다운받은 파일을 배치하는 것입니다.
목록에 새로운 저장소를 추가하려면 +Repository 를 클릭하고, 팝업 메뉴에서 저장소의 종류를 선택합니다. HTTP 저장소를 추가하는 과정을 진행해보겠습니다.
몬티첼로를 열고 +Repository 버튼을 누르고 HTTP를 선택합니다. Dialog를 읽고 편집합니다.
MCHttpRepository
location: 'http://squeaksource.com/SqueakByExample'
user: ''
password: ''
그 다음 선택한 저장소에 대한 저장소 브라우저(repository browser)를 열기 위해 Open을 클릭합니다. 그림 6.13과 같은 모습이 보일겁니다. 왼쪽은, 대상이 되는 저장소에 있는 모든 패키지의 목록이며, 만약 패키지중 하나를 선택하면, 오른쪽에 있는 패널에는 선택 패키지에 대한 이 저장소에 있는 모든 버전을 보여줍니다.
만약 왼쪽목록에 나온 버전중 하나를 선택하면, 선택한 버전을(현재의 이미지에 로드하지 않고) Browse(검색)하실 수 있으며, 현재의 이미지로 Load 함으로써 사용자의 이미지에 발생한 Changes 들을 볼 수 있습니다. 또한 패키지의 버전에 대한 Copy 상태를 만들고, 다른 저장소에 저장할 수도 있습니다.
이렇듯이, 패키지의 이름을 포함하고 있는 버전의 이름은, 버전의 저자와 버전 번호의 머릿글자입니다. 버전 이름은 또한 저장소에 있는 파일 이름이기도 합니다. 이 이름들을 절대로 변경하시지 마세요. 몬티첼로의 수정 작업은 이 이름들을 기초로 진행됩니다. 몬티첼로 버전 파일들은 단지 Zip archives 입니다. 그리고 궁금하다는 이유로 zip 도구를 이용해서 파일 압축을 해제할 수 도 있지만, 파일의 내부를 살펴보는 제일 좋은 방법은 몬티첼로를 사용하는 것입니다.
몬티첼로로 패키지를 만들려면, 두 가지 작업을 하셔야 합니다: 약간의 코드 작성, 그리고 그것에 대해 몬티첼로에게 알려줘야 합니다.
SBE-Monticello 라는 이름의 카테고리를 만들고, 그림 6.14에 보이듯이 몇 개의 클래스를 만든 카테고리에 추가합니다. 기존에 있는 클래스에 메서드를 만들고, 그림 6.15에서 볼 수 있듯이 이름짓기규칙등을 사용해서 만들어진 메서드를 새로만든 패키지에 추가시킵니다
몬티첼로에게 이렇게 만들어진 패키지에 관해 알려주려면, +Package 를 클릭하고, 추가를 원하는 패키지의 이름을 입력 합니다. 이 경우는 "SBE" 를 입력하도록 하겠습니다. 몬티첼로는 SBE를 몬티첼로 내부의 패키지 목록에 추가합니다. 패키지 엔트리는 이미지에 있는 버전이 어떤 저장소에도 기록되지 않았다는 것을 알려주기 위해 *(별표)로 해당 항목을 표시합니다.
저장된 결과가 없는 처음에는, 그림 6.16에서 보이는 것 처럼, 저장소 목록에는 package-cache 하나만이 현재 패키지와 관련된 저장소로 나타나게 됩니다. 현재 상황은 우무문제 없습니다: 우리는 여전히 코드를 저장할 수 있으며, 저장작업은 코드가 package-cache 에 기록되도록 해줍니다. Save를 클릭하면, 그림 6.17에서 보이는 것처럼 잠시후 저장될 패키지의 버전에 대한 로그 메시지 입력을 요구합니다. 메시지를 입력하고 Accept 하면, 몬티첼로는 패키지를 저장합니다. 작업이 진행됐음을 나타내기 위해 몬티첼로 패키지 패널에 있는 이름에있는 별표가 제거될 것이며 새로 버전이 추가됩니다.
만약 패키지에 변경사항이 생겼다면(클래스 중의 하나에 메서드를 추가하라는등의 작업) *(별표)는 패키지가 저장되지 않은 변경사항이 있다는 것을 알려주며 * 표가 다시 나타납니다. 만약 package-cache 에 있는 저장소 브라우저를 열면, 이미 저장되었던 버전을 선택할 수 있고 Changes 들과 다른 버튼들을 사용할 수 있습니다. 물론 저장소에 새로운 버전을 저장할 수도 있습니다. 일단 저장소 뷰(the repository view)를 Refresh 하셨다면, 그림 6.18과 같이 될것입니다.
package-cache가 아닌 다른저장소에 새로운 패키지를 추가하려면, 먼저 몬티첼로가 추가하려는 저장소에 관하여 알고있도록 만들어야 합니다.
그 다음 package-cache 저장소 브라우저에 있는 Copy 를 사용할 수 있으며, 패키지의 복사대상이될 저장소를 선택하실 수 있습니다. 또한 그림 6.19에 보이는 것처럼 노랑버튼 메뉴 아이템 add to package 를 사용하여 패키지와 원하는 저장소를 조합할 수 있습니다. 일단 패키지가 저장소에 관해서 알게 되면, 몬티첼로 브라우저에 저장소와 패키지를 선택하고 Save 를 클릭하여 새로운 버전을 저장하면 됩니다.
물론, 당신은 SqueakSource에 있는 SqueakByExample 의저장소인 world저장소에 대해 읽기read는 가능하지만 , world저장소에 쓰기write는 불가능하기때문에, 만약 world저장소에 쓰기를 시도하고 저장하면, 반드시 에러메시지가 발생합니다. 그럼에도 불구하고, http://www.squeaksource.com 에 있는 웹 인터페이스the web interface 를 사용하여 사용자 자신만의 저장소를 만들 수 있으며, 당신의 작업을 저장하기 위해 이 웹 인터페이스를 사용할 수 있습니다. 이 웹 인터페이스는 특별히, 만약 여러 개의 컴퓨터를 사용하는 경우, 친구와 당신의 코드를 공유하기 위한 메커니즘으로 매우 유용합니다. 만약 쓰기 권한을 갖고 있지 않은 저장소에 쓰기 및 저장을 시도해도, 서버에는 저장되지 않으며 저장하려는 버전은 package-cache에 기록됩니다.
쓰기 권한이 없는경우 저장소에 저장을 할 수 없기때문에, 필요한경우 기존의 저장소 정보를 편집(몬티첼로 브라우저에서 노랑 버튼)하거나 또는 다른 저장소를 선택하고, 그 다음 패키지 캐쉬 브라우저(package-cache browser)로 부터 Copy를 사용하여 내용을 복구(recover)하여야 합니다.