이클립스IDE :: 그루비 플러그인 :: Exception 메시지 팁

이클립스IDE :: 그루비 플러그인 :: Exception 메시지 팁

이클립스에서 플러그인을 설치하여 그루비를 사용중이라면 exception 내용이 필요없이 너무 많아서 골머리를 앓고 있을 것이다.

예를 들면 다음코드를 보자.

def onPurposeException() {
     new File(‘noexitfile.txt’).eachLine {
         println it
     }
}
 
onPurposeException()

이 코드를 이클립스에서 실행한 후 콘솔창을 보면 결과가 다음과 같이 나온다.

보시다시피 정작 필요한 메시지는 19번째 라인에 있다. 나머지는 그루비 개발자에게는 필요없는 메시지다.

   1: Exception in thread “main” java.io.FileNotFoundException: noexitfile.txt (지정된 파일을 찾을 수 없습니다)
   2:     at java.io.FileInputStream.open(Native Method)
   3:     at java.io.FileInputStream.<init>(Unknown Source)
   4:     at groovy.util.CharsetToolkit.<init>(CharsetToolkit.java:68)
   5:     at org.codehaus.groovy.runtime.DefaultGroovyMethods.newReader(DefaultGroovyMethods.java:7499)
   6:     at org.codehaus.groovy.runtime.DefaultGroovyMethods.eachLine(DefaultGroovyMethods.java:6797)
   7:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   8:     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   9:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  10:     at java.lang.reflect.Method.invoke(Unknown Source)
  11:     at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:51)
  12:     at org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod.invoke(NewInstanceMetaMethod.java:54)
  13:     at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:599)
  14:     at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:904)
  15:     at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:740)
  16:     at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:761)
  17:     at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:749)
  18:     at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:167)
  19:     at Test.onPurposeException(Test.groovy:12)
  20:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  21:     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  22:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  23:     at java.lang.reflect.Method.invoke(Unknown Source)
  24:     at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:95)
  25:     at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:599)
  26:     at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:904)
  27:     at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrentN(ScriptBytecodeAdapter.java:77)
  28:     at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnCurrent0(ScriptBytecodeAdapter.java:109)
  29:     at Test.run(Test.groovy:17)
  30:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  31:     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  32:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  33:     at java.lang.reflect.Method.invoke(Unknown Source)
  34:     at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:95)
  35:     at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:599)
  36:     at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:904)
  37:     at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:740)
  38:     at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:773)
  39:     at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:753)
  40:     at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:402)
  41:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  42:     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  43:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  44:     at java.lang.reflect.Method.invoke(Unknown Source)
  45:     at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:95)
  46:     at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:599)
  47:     at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1077)
  48:     at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:744)
  49:     at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:167)
  50:     at Test.main(Test.groovy)

이렇게 필요없는 메시지를 제고하고 보고 싶다면 다음 함수를 추가해서 사용하기 바란다.

def pst(e){
    def newTrace = []
    e.stackTrace.each{te->
        if (te.toString() =~ /.*groovy:d*/) newTrace << te
    }
    e.stackTrace = newTrace
    e.printStackTrace()
}

위 함수를 이용하여  try catch문을 적용해 보자.

try {
    onPurposeException()
} catch(Exception _) {
    pst(_)
}

결과는 아래와 같이 깔끔하게 나온다.
보시다시피 어느 라인에서 문제가 발생하는지 한눈에 알아볼 수 있다.

java.io.FileNotFoundException: noexitfile.txt (지정된 파일을 찾을 수 없습니다)
    at Test.onPurposeException(Test.groovy:12)
    at Test.run(Test.groovy:20)

이클립스 그루비 플러그인은 아직도 개발중인 상태인데 약간 더딘 감이 있다.

다음 버전에서는 더 좋은 기능을 기대해 보기로 하자.

 

Reference : 그루비 이클립스 플러그인 FAQ

2008.06.25 by gilbird

그루비(Groovy) – 자바와의 차이점

그루비(Groovy) - 자바와의 차이점
2008.5.13 translation & editing by gilbird

원문:http://groovy.codehaus.org/Differences+from+Java

 

그루비는 되도록 자바 개발자에게는 자연스럽게 와닿을 수 있도록 노력했다. 그루비를 설계할 때, 자바 배경지식을 가진 사람이 그루비를 학습한다고 하면 최소한의 차이점만을 느끼도록 한다는 원칙으로 만들었다.

다음은 자바와 그루비의 주요 차이점이다.

기본 import

아래 패키지와 클래스는 기본적으로 import되는 것들이다. 따라서, 명시적으로 import문으로 아래 패키지, 클래스를 적지 않아도 포함되어 있다.

  • java.io.*
  • java.lang.*
  • java.math.BigDecimal
  • java.math.BigInteger
  • java.net.*
  • java.util.*
  • groovy.lang.*
  • groovy.util.*

일반적인 차이점

다음은 그루비를 시작하는 자바 개발자가 흔히 겪는 일들이다.

  • ==는 모든 형식에서 동등함을 의미한다. 자바에서는 이상하게도 ==가 기본형(primitive type)의 동등함은 물론 객체가 일치함을 뜻하기도 한다. 그루비에서는 오토박싱(autoboxing을 사용하므로 자바 개발자에게는 아주 혼란스러울 수도 있다. ( x==5는 x가 5라면 대부분 false일 것이다. 그래서 그루비에서는 ==는 equals()를 뜻한다.) 객체 일치가 필요하다면 foo.is(bar)와 같이 “is” 메서드를 사용하면 된다. 이 방식은 null에서는 동작하지 않지만 foo==null과 같이는 사용할 수 있다.
  • in은 키워드다. 따라서 변수명으로 사용하면 안된다.
  • 배열은 아래와 같이 선언하면 안된다.
    int[] a = {1,2,3};
    대신 아래와 같이 쓴다.
    int[] a = [1,2,3]
  • 아래과 같은 for 루프를 주로 썼다고 해보자.
    for (int i=0; i < len; i++) {…}
    그루비에서는 위와 같이 쓸 수 있다. 하지만 아래와 같이 하나의 카운트 변수만을 사용할 수도 있다.
    for (i in 0..len-1) {…}for (i in 0..<len) {…}len.times {…}

주의할 점

  • 세미콜론은 선택사항이다. 취향에 따라 사용하면 된다. (하지만 2개 이상의 명령문을 사용할 때에는 넣어야 한다.)
  • return 키워드는 선택사항이다.
  • this 키워드를 (this 클래스를 참조하는) 정적 메서드에서 사용할 수 있다.
  • 메서드와 클래스는 기본적으로 public이다.
  • 그루비의 protected는 자바의 protected와 같은 의미이다. 즉, 동일한 패키지와 상속한 클래스에서 protected 멤버를 액세스할 수 있다.
  • Inner 클래스는 지원하지 않는다. 대신 클로져를 사용하기 바란다.
  • 메소드 식의 throw 절은 그루비 컴파일러에서 검사하지 않는다.
  • 자바에서의 undefined members 혹은 인자 형식 오류 등에 대하여 컴파일 오류가 발생하지 않을 것이다.
    런타임 vs 컴파일타임, 정적 vs 동적 글을 참고하기 바란다.

특별한 차이점

자바 프로그래머는 명령어 종료로 세미콜론(;)을 사용하며 클로져는 쓰지 않는다. 또한 클래스 정의에서 인스턴스 초기화를 한다. 아래 코드를 보기 바란다.

class Trial {  private final Thing thing = new Thing ( ) ;  { thing.doSomething ( ) ; }}

많은 그루비 프로그래머는 세미콜론을 사용하면 산만하고 중복이 많아 쓰길 꺼려 한다. (하지만 어떤 사람들은 항상 사용한다. 코딩스타일에 따라 다르다.) 위 코드를 아래와 같이 쓰면 문제가 생긴다.

class Trial {  private final thing = new Thing ( )  { thing.doSomething ( ) }}

위 코드는 MissingMethodException이 throw될 것이다.

이 상황에서의 문제는 줄바꿈(newline)은 명령 종결자가 아니라서 다름 블록을 클로져로 인식하여 Thing 생성자에 인자를 전달해 버린다. 이상하게 느껴지겠지만 사실이다. 의도한 방식으로 인스턴스를 초기화 하고 싶다면 세미콜론을 사용하는 것이 필수적이다.

class Trial {  private final thing = new Thing ( ) ;  { thing.doSomething ( ) }}

위 코드의 초기화 정의 다음 블록은 확실히 인스턴스 초기화를 수행한다.

다른 문서에서 알아야 할 몇가지 함정과 회피하기 위한 최선의 예를 참고하기 바란다.

자바에서는 사용 불가능한 그루비에 추가된 새로운 기능

  • 클로져
  • 리스트와 맵에 대한 네이티브 문법
  • GroovyMarkup, GPath 지원
  • 정규식에 대한 네이티브 지원
  • 여러가지 모양의 iteration과 강력한 switch문
  • 동적, 정적 형식을 지원함으로써 메서드, 필드, 변수의 형식을 생략해도 됨
  • 문자열 안에 식을 넣을 수 있음
  • JDK에 수많은 헬퍼 메서드가 추가됨
  • 빈(bean)의 속성을 쓰고 이벤트 리스너를 추가하는데 간단한 문법
  • ?. 연산자를 이용한 안전한 액세스. 예를 들면 “variable?.field”와 “variable?.method()”로 더이상 중첩루프 덩어리를 만들어 널체크를 안해도 됨

그루비(Groovy) – 클로져(Closure)란?

그루비(Groovy) - 클로져(Closure)란?
2008.4.29 translation & editing by gilbird

원문: http://groovy.codehaus.org/Closures

 

gilbird: 위키피디아에서 클로져(Closure)란 함수를 영역안에 묶어 버리는 추상적인 묶음이라고 표현한다. 그루비에서 클로져를 사용하는 방법을 알아보기로 하자.

 

클로져(Closure)란 무엇인가?

그루비 클로져는 코드 블록 혹은 메서드 포인터와 같다. 클로져는 정의 후  나중에 실행할 코드 조각을 말한다.

간단한 예제
def clos = { println “hello!” }println “Executing the closure:”clos()                          // “hello!”를 출력한다.

위의 예에서 “hello!”는 클로져를 정의할때가 아니라 호출할때 출력된다는 점에 주목하기 보란다.

클로져는 정의한 영역의 변수에 묶일 수 있다.

def localMethod() {  def localVariable = new java.util.Date()  return { println localVariable }}def clos = localMethod()println “Executing the closure:”clos()                          //“localVariable”을 정의했을 때 날짜를 출력한다.

파라메터 (Parameters)

클로져 파라메터는 아래와 같이 -> 토큰 앞에 나열한다.

def clos = { a, b -> print a+b }clos( 5, 7 )                       //“12”를 출력한다.

-> 토큰은 클로져 정의에 파라메터가 하나 뿐이면 생략 가능한다. (gilbird: 아래 It 설명을 보기 바란다.)

명시적 변수(Implicit variables)

클로져 안에서 여러 변수가 특별한 의미로 쓰인다.

It

인자 하나만을 받아들이는 클로져가 있다면 다음과 같이 클로져 정의에서 파라메터를 뺄 수 있다.

def clos = { print it }clos( “hi there” )              // “hi there”가 출력된다.
this, owner, delegate

this: 자바에서 this는 클로져를 정의한 클래스를 지칭한다.

owner: 둘러싼 객체 (this나 둘러싼 클로져)

delegate: 기본적으로 owner와 동일하지만 builder나 ExpandoMetaClass에서와 같이 변경가능함

예:

class Class1 {  def closure = {    println this.class.name    println delegate.class.name    def nestedClos = {      println owner.class.name    }    nestedClos()  }}def clos = new Class1().closureclos.delegate = thisclos()/*  출력: Class1 Script1 Class1$_closure1  */
클로져와 메서드 인자

메서드에서 클로져를 마지막 인자로 받는다면 아래와 같이 클로져를 인라인으로 정의할 수 있다.

def list = [‘a’,‘b’,‘c’,‘d’]def newList = []list.collect( newList ) {  it.toUpperCase()}println newList           //  [“A”, “B”, “C”, “D”]

위 예에서 collect 메서드는 List와 클로져 인자를 받아들인다. 위 코드는 아래과 같이 표현할 수도 있다.

def list = [‘a’,‘b’,‘c’,‘d’]def newList = []def clos = { it.toUpperCase() }list.collect( newList, clos )assert newList == [“A”, “B”, “C”, “D”]

더 많은 정보

그루비에서는 java.lang.Object를 상속하여 여러 메서드가 클로져와 인자를 받아들이도록 했다. 클로져의 실제적인 사용법에 대해서는 Object를 확장하는 GDK를 참고하기 바란다.

  • 클로져 – 공식적인 정의
  • 클로져 – 비공식적 가이드

그루비(Groovy) 튜토리얼 6 – GSQL

그루비(Groovy) 튜토리얼 6 - GSQL
2008.4.22 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+6+-+Groovy+SQL

그루비 SQL

이번 튜토리얼에서는 앤드류 글로버(Adrew Glober)가 작성한 그루비 SQL에 대한 글의 일부를 보도록 하자. 아래는 문자열 선언부에 변수를 넣는 새로운 언어 구성체이다.  아래를 보도록 하자.

piEstimate = 3;println(“Pi is about ${piEstimate}”);println(“Pi is closer to ${22/7}”);

보시다시피 문자열에서 그루비는 ${}를 그루비 식으로 인식한다.

이 형식은 아래와 같이 보다 확장할 수 있다.

간단한 질의 실행하기

첫번째 그루비 SQL 코드는 세 줄이다.

import groovy.sql.Sqlsql = Sql.newInstance(“jdbc:jtds:sqlserver://serverName/dbName-CLASS;domain=domainName”, “username”,                     “password”, “net.sourceforge.jtds.jdbc.Driver”)sql.eachRow(“select * from tableName”, { println it.id + ” — ${it.firstName} –“}

첫번째 줄은 자바 import이다. Sql 객체의 전체 이름을 알리고 있다. 두번째 줄은 SQL 데이터베이스에 새로운 연결을 하고 sql 변수에 연결을 저장한다.

이 코드는 MS SQL 서버로 연결하는 jTDS 연결용으로 작성했다. 각자 username과 password와 같이 사용하고자하는 데이터베이스에 대한 파라메터를 조절하기 바란다.

마지막 세번째 줄은 sql의 eachRow 메서드에 두개의 인자를 전달하는데 첫번째 인자는 질의 문자열이고 두번째 인자는 값을 출력하는 클로져이다.

클로저의 “it”은 두가지 다른 방식으로 액세스 한다는 점을 주의깊게 보기 바란다. 첫번째는 it의 id를 액세스하는 간단한 필드 참조이고 두번째는 앞서 언급한 그루비 식이 들어있다.

따라서 한 열에 대한 출력은 아래와 같이 나온다.

001 — Lane —

DB에서 값 가져오기

DB의 한 열에서 한 개 이상의 컬럼 값이 필요하다면 아래와 같이 하면 된다.

row = sql.firstRow(“select columnA, columnB from tableName”)println “Row: columnA = ${row.columnA} and columnB = ${row.columnB}”

복잡한 질의 수행하기

위 예제들은 아주 간단했는데 insert, delete, update 등 복잡한 데이터 처리 질의에 대해서 다루는 경우 그루비 SQL이 아주 유용하다. 이 때 클로저를 쓸 필요없이 그루비의 Sql 객체의 execute와 executeUpdate 메서드를 쓰면 된다. 이 메서드들은 기존 JDBC Statement 클래스에 있는 것들과 이름과 동작이 유사하다.

아래는 ${} 문법으로 변수를 치환하여 insert를 수행하는 간단한 예이다. 이 코드는 새로운 열을 people 테이블에 insert한다.

firstName = “yue”lastName = “wu”sql.execute(“insert into people (firstName, lastName) “+  ” values (‘${firstName}’, ${lastName})”)

위의 예에서 insert문의 모든 문자열에 작은 따옴표를 넣어야 하는 점에 유의해야 한다. 이 방식은 바람직하진 않다 (데이터에 작은 따옴표 문자가 있을 경우를 생각해보라). 보다 나은 방식은 아래와 같이 prepared statement를 사용하는 것이다.

firstName = “yue”lastName = “wu”sql.execute(“insert into people (firstName, lastName) “+  ” values (?,?)”, [firstName, lastName])

위의 예를 보면 insert문에서 넣고자 하는 데이터를 ?로 표시하고 실제 넣을 값은 배열 인자로 전달하면 된다. update도 유사한 방식이다. 아래 예를 보면 executeUpdate 메서드 역시 질의에서 ?에 들어갈 값을 가져온다.

comment = “Lazy bum”sql.executeUpdate(“update people set comment = ? where id=002”, [comment])

delete는 질의 문법이 다른것 외에는 위와 동일하다.

sql.execute(“delete from word where word_id = ?” , [5])

그루비(Groovy) 튜토리얼 5 – 정규식 결과 집합 만들기 (Capturing regex groups)

그루비(Groovy) 튜토리얼 5 - 정규식 결과 집합 만들기 (Capturing regex groups)
2008.4.10 translation & editing by gilbird
원문: wiki-snapshot.pdf  pp. 263-266

Naver 태그: 그루비,groovy,자바,java,tutorial

검색결과 집합 (Capture Groups)

그루비에서 가장 유용한 특징 중의 하나로 정규식으로 데이터에서 정규식 검색 결과 집합을 구성하는 기능이 있다. 예를 들어 다음과 같이  England의 Liverpool의 위치 데이터를 추출한다고 해보자.

locationData = “Liverpool, England: 53° 25? 0? N 3° 0? 0?”

데이터 추출을 위하여 string의 split()함수를 써서 Liverpool과 England 사이의 쉼표, 기타 특수문자를  제거한다. 아니면 정규식 한 줄로 해결할 수도 있는데 식을 만들고 나면 다소 복잡해 보일 수도 있다.  우선 관심있는 것들을 모두 괄호로 묶어 놓는다.

myRegularExpression = /([a-zA-Z]+), ([a-zA-Z]+): ([0-9]+). ([0-9]+). ([0-9]+). ([A-Z])([0-9]+). ([0-9]+). ([0-9]+)./
다음은 ~= 연산자로 “matcher”를 정의한다.
matcher = ( locationData =~ myRegularExpression )

matcher변수는 그루비에서 향상시킨 java.util.regex.Matcher를 내장하고 있다. 데이터는 Matcher 객체로부터 자바에 있는 것처럼 액세스할 수 있다. 그루비 개발자가 데이터를 가져오는 방법은 matcher를 써서 2차원 배열인 것처럼 사용하는 것이다. 2차원 배열은 배열의 배열이다. 위의 경우에 배열의 첫번째는 문자열이 정규식에 각각 일치한 값들이다. 이 예에서 정규식은 한번만 일치하며 2차원 배열의 첫번째 엘리먼트는 한개 뿐이다. 다음 코드를 보자.

matcher[0]

위 식의 결과는 아래와 같이 나와야 한다.

[“Liverpool, England: 53° 25? 0? N 3° 0? 0?”, “Liverpool”, “England”, “53”, “25”, “0”, “N”,“3”, “0”, “0”]

그리고 배열의 두번째 차원을 액세스해서 찾아보고자하는 검색 결과 집합(capture group)을 액세스 할 수 있다.

if (matcher.matches()) {    println(matcher.getCount()+ ” occurrence of the regular expression was found in the string.”);    println(matcher[0][1] + ” is in the “ + matcher[0][6] + ” hemisphere. (According to: “         + matcher[0][0] + “)”)}

정규식을 이용하여 얻을 수 있는 이점은 데이터가 규칙적(well-formed)인지 볼 수 있다는 것이다. 즉  locationData가 “Could not find location data for Lima, Peru”라면 if문 안을 실행하지 않을 것이다.

검색결과외 집합 (Non-matching Groups)

검색 결과 이외의 집합을 만드는 식을 사용하는 것이 좋을 수도 있는데 괄호안의 맨앞에 ?: 두 글자를 넣으면 된다. 예를 들어 몇몇 사람의 중간 이름이 무것이든지 없애고 맨앞과 맨뒤 글자를 뒤바꿔 출력 하고자 한다면 아래와 같이 한다.

names = [    “Graham James Edward Miller”,    “Andrew Gregory Macintyre”]printClosure = {    matcher = (it =~ /(.*?)(?: .+)+ (.*)/); // 중간에 검색결과외 집합이 있다.    if (matcher.matches())        println(matcher[0][2]+“, “+matcher[0][1]);}names.each(printClosure);

위의 결과는 아래와 같다.

Miller, GrahamMacintyre, Andrew

위와 같이 하면 성이 두번째 일치 집합에 들어 있음을 알 수 있다.

치환 (Replacement)

정규식으로 할 수 있는 가장 간단하고 유용한 작업은 문자열의 일부를 치환하는 것인데 java.util.regex.Matcher (이 객체는 myMatcher = (“a” += /b/)와 같은 식을 사용하면 나온다)의 replaceFirst()와 replaceAll() 함수를 쓰면 된다.

Harry Potter 이름을 전부  Tanya Grotter로 치환해서 J.K Rewlings의 책을 재판매하고 싶다고 해보자 (누군가 이런 짓을 했다. 궁금하면 검색해보라).

excerpt = “At school, Harry had no one. Everybody knew that Dudley’s gang hated that odd Harry Potter “+    “in his baggy old clothes and broken glasses, and nobody liked to disagree with Dudley’s gang.”;matcher = (excerpt =~ /Harry Potter/);excerpt = matcher.replaceAll(“Tanya Grotter”);matcher = (excerpt =~ /Harry/);excerpt = matcher.replaceAll(“Tanya”);println(“Publish it! “+excerpt);

이 경우 Harry Potter의 이름, 성+이름 두 가지에 대해서 치환이 된다.

최소동작 연산자 (Reluctant Operators)

?, +, *는 게걸스러운 연산자라서 가능한 많은 입력을 일치 시키려고 한다. 때로는 이 방법이 원하지 않는 것일 수도 있다. 아래는 15세기 교황 리스트를 가지고 이야기 해보자.

popesArray = [    “Pope Anastasius I 399-401”,    “Pope Innocent I 401-417”,    “Pope Zosimus 417-418”,    “Pope Boniface I 418-422”,    “Pope Celestine I 422-432”,    “Pope Sixtus III 432-440”,    “Pope Leo I the Great 440-461”,    “Pope Hilarius 461-468”,    “Pope Simplicius 468-483”,    “Pope Felix III 483-492”,    “Pope Gelasius I 492-496”,    “Pope Anastasius II 496-498”,    “Pope Symmachus 498-514”]

위 예에서 (일련번호나 수식어구 없는) 이름만을 파싱해 내는 정규식을 만들어 보자.

/Pope (.*)(?: .*)? ([0-9]+)-([0-9]+)/

위 식은 아래와 같이 나누어 볼 수 있다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작Pope0개 이상의 글자검색결과외 집합: 공백문자와 0개 이상의 글자숫자숫자정규식 끝

위의 모든 예에서 첫번째 일치 집합은 교황의 이름만이 나올 것으로 기대 했으나 실제로 나온 결과는 수식어 까지 인식이 되버린다. 예를 들어 첫번째 교황은 다음과 같이 쪼개진다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작PopeAnstasius I 399401정규식 끝

위 사실로 보아 첫번째 결과 집합에서 너무 많은 인식을 하고 있다. 첫번째 결과 집합에서는 Anatasius 만 가져오고 수식어구는 두번째 결과 집합에 들어가길 원했다. 방법을 바꾸어 첫번째 결과 집합에 최소한의 입력만 인식하도록 해보자. 이 경우는 공백 전까지의 모든 것이 해당된다. 자바 정규식에서는 *, +, ? 연산자의 최소 동작(reluctant) 버전을 지원한다. *+? 세가지 연산자 중 하나를 최소로 동작하게 하려면 간단하게 연산자 다음에 ?를 넣으면 된다(*?, +?, ??). 그래서 새로운 정규식은 아래와 같다.

/Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/

이제 새로운 정규식으로 난이도 높은 입력의 하나로 Pope Hilarius를 처리해 보도록 하자. 결과는 아래와 같다.

/Pope(.*)(?: .*)?([0-9]+)([0-9]+)/
정규식 시작PopeLeoI the Great440461정규식 끝

이 결과가 바로 우리가 원하는 것이다.


테스트를 위하여 다음 코드를 실행해 보기 바란다.

popesArray = [    “Pope Anastasius I 399-401”,    “Pope Innocent I 401-417”,    “Pope Zosimus 417-418”,    “Pope Boniface I 418-422”,    “Pope Celestine I 422-432”,    “Pope Sixtus III 432-440”,    “Pope Leo I the Great 440-461”,    “Pope Hilarius 461-468”,    “Pope Simplicius 468-483”,    “Pope Felix III 483-492”,    “Pope Gelasius I 492-496”,    “Pope Anastasius II 496-498”,    “Pope Symmachus 498-514”]myClosure = {    myMatcher = (it =~ /Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/);    if (myMatcher.matches())        println(myMatcher[0][1]+“: “+myMatcher[0][2]+” to “+myMatcher[0][3]);}popesArray.each(myClosure);
 
위 코드의 결과 비교차원에서 처음 제시한 정규식도 넣어서 실행해 보기 바란다. 

이클립스 IDE에서 그루비(Groovy) 사용하기

이클립스 IDE에서 그루비(Groovy) 사용하기

2008.03.31 written by gilbird

이클립스 플러그인을 설치하면 그루비를 편집 및 실행해볼 수 있다.
다음 단계대로 진행하면 된다.

이클립스 버전 호환성

이클립스 IDE에서 그루비(Groovy) 사용하기 Eclipse 3.0 : 동작하지 않음
이클립스 IDE에서 그루비(Groovy) 사용하기 Eclipse 3.1 : 동작하지 않음
이클립스 IDE에서 그루비(Groovy) 사용하기 Eclipse 3.2 : 동작함
이클립스 IDE에서 그루비(Groovy) 사용하기 Eclipse 3.3 : 동작함 – (최소 테스트로 검증함)

플러그인 설치

  • Help > Software Updates > Find and Install… 클릭
  • Search for new features to install 선택후  Next 클릭
  • New Remote Site 클릭
  • 새창이 뜨면 각 항목에 다음과 같이 입력
    이클립스 IDE에서 그루비(Groovy) 사용하기
  • 방금 만든 Groovy를 선택하고 Finish 누름
  • Select the features to install 아래 Groovy 체크박스 선택 후 Next 클릭
  • Agrreement를 허용하고 Next 누름
  • 디폴트 위치를 확인하고 Finish 누름 (이후 플러그인 다운로드 진행)
  • 플러그인이 서명이 없다고 경고가 나오면 Install이나 Install All을 클릭

여기까지 진행하면 일단 플러그인 설치가 완료되고 이클립스가 다시 실행된다.


그루비 프로젝트 만들기

기본 그루비 프로젝트를 만들려면 다음과 같이 한다.

  • File > New > Project 선택
  • Java Project를 선택하고 Next 클릭
  • Project Name에 프로젝트명 입력(예를 들면 Groovy)
  • Project layout란에 Create separate source and output folders 선택하고 Finish 클릭
  • Package Explorer에서 새로 만든 프로젝트를 찾아 오른쪽 클릭하여 팝업 밑에 Groovy > Add Groovy Nature 선택

이렇게 하면 src와 bin-groovy 폴더 그리고 여러 라이브러리가 생길 것이다. 그리고 이클립스가 빌드한 파일이 저장되는 bin 폴더도 있을 것이다. 다음 작업으로는 기본 output 폴더를 bin-groovy로 설정하여 src 폴더와 연결하여 디버거가 관련 파일과 클래스를 찾아볼 수 있도록 한다.

  • Package Explorer에서 Groovy 프로젝트를 선택하여 오른쪽 클릭하고 Build Path > Configure Build Path 선택
  • Source 탭 선택하고 Browse 버튼을 클릭하여 Default output folder의 bingroovy-bin으로 변경
  • OK 누름, 이제 끝이다!

왜 bin을 안쓰고 bin-groovy로 변경해야 하는지는 원문에서 잘 모르겠다고 나온다 ㅋㅋ 며느리도 몰라~

 

그루비 편집 및 실행화면

프로젝트 탭에서 클래스 파일을 추가하고 파일명을 입력하면
다음과 같이 [파일명].groovy 파일이 만들어진다.

이클립스 IDE에서 그루비(Groovy) 사용하기


이제 실행을 누르면 아래 콘솔창에 결과가 나온다.


이클립스 IDE에서 그루비(Groovy) 사용하기

 

그 외…

기타 플러그인 개발 관련 내용은 원문을 보기 바란다.

원문: http://groovy.codehaus.org/Eclipse+Plugin

그루비(Groovy) 튜토리얼 4 – 정규식(Regular Expression) 기본

그루비(Groovy) 튜토리얼 4 - 정규식(Regular Expression) 기본

2008.3.25 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+4+-+Regular+expressions+basics

정규식(Regular Expression)

정규식은 텍스트 처리의 스위스 아미 나이프라고 할 수 있다. 정규식으로 문자열의 패턴을 찾아 추출할 수 있다. 가장 간단한 정규식의 예로는 문자와 숫자가 있다. 그리고 가장 간단한 식으로는 ==~를 사용한 정규식이 있다. 예를 들어 ‘potatoe’와 문자열이 일치하는지 보려면 다음과 같이 한다.

“potatoe” ==~ /potatoe/

groovyConsole에 위 식을 입력하여 실행하면 true를 리턴할 것이다. 몇가지 주목할 만한 점이 있다. 첫번째는 ==와 유사한 ==~ 연산자인데 정확히 일치하는 패턴에 대해서만 일치한다. 두번째는 정규식이 /로 둘러쌓아서 그루비에게 일반 문자열이 아닌 정규식임을 알린다.

정확한 철자가 일치하는지 체크하길 원하는데 ‘e’ 다음에 ‘?’를 추가하면 e는 선택사항(있어도 되고 없어도 됨)이다. 다음 정규식은 true다.

“potatoe” ==~ /potatoe?/

정확한 철자도 일치한다.

“potato” ==~ /potatoe?/

다음은 앞의 두경우 모두 해당되지 않으며 일치하지 않는다.

“motato” ==~ /potatoe?/

다음은 정규식을 가진 간단한 대수식(boolean expression)을 정의하는 방법이다. 정규식을 테스트하는 메서드를 만들어보자. 예를 들어 Pete Winsniewski의 성과의 일치여부를 체크하는 코드를 만들어 보자.

def checkSpelling(spellingAttempt, spellingRegularExpression) {        if (spellingAttempt ==~ spellingRegularExpression) {               println(“Congratulations, you spelled it correctly.”)         } else {               println(“Sorry, try again.”)        }}theRegularExpression = /Wisniewski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnewski”, theRegularExpression)

위 코드에서는 몇가지 특이한 점이 있다. 첫번째로 함수를 정의하였다(실제로는 메서드지만 두 단어를 혼용해서 쓰겠다). 함수는 클로저와 유사한 코드의 집합이다. 클로저는 익명일 수 있지만 함수는 항상 이름을 가지고 있다. 한번 정의하면 나중에 계속 쓸 수 있다.

checkSpelling 함수에서 if문은 주어진 파라메터 spellingAttempt와 spellingRegularExpression의 패턴이 일치하는지 ==~ 연산자로 검사한다.

checkSpelling 함수를 이용하여 이름의 중앙에 ‘w’를 가지지 않은 문자열을 찾고 싶은 경우 다음과 같이 할 수 있다:

theRegularExpression = /Wisniew?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

checkSpelling함수의 spellingRegularExpression 인자로 들어간 theRegularExpression값에 ? 한개는 바로 앞의 문자(‘w’)는 선택사항이라는 것이다. 이 코드를 spellingAttempt에 다른 w의 위치에 다른 철자를 넣어 두 가지 철자법 ‘Wisniewski’와 ‘Wisnieski’만 일치함을 증명해보자.

?는 정규식에서 특별한 의미임을 기억하기 바란다.

단어 중앙의 “ie” 순서가 바뀌어도 일치한 것으로 보이도록 해보자.

theRegularExpression = /Wisn(ie|ei)w?ski/checkSpelling(“Wisniewski”, theRegularExpression)checkSpelling(“Wisnieski”, theRegularExpression)checkSpelling(“Wisniewewski”, theRegularExpression)

위의 정규식으로 철자에 대해서 이야기 해보자. ‘Wisniewski”, “Wisneiwski”, “Wisnieski”, Wisneiski” 4가지 철자가 일치하는 것으로 나온다. 막대 문자 ‘|’는 왼쪽이나 오른쪽 항목(위의 경우에는 “ie”나 “ei”)이 수락 가능한 것임을 말한다.  괄호는 간단하게 관심 부분의 시작과 끝임을 표시한다.

정규식 중 흥미로운 특징중의 하나로 문자집합을 지정하여 일치를 허용하는 방법이 있는데 꺽쇄괄호[]를 사용한다.

다음과 같이 Pete의 성에 다양한 철자법 오류를 시도해 보자.

theRegularExpression = /Wis[abcd]?niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 중의 하나 혹은 없음
theRegularExpression = /Wis[a-zA-Z]niewski/ // 소문자나 대문자가 필요함
theRegularExpression = /Wis[^abcd]niewski/ // ‘a’, ‘b’, ‘c’ , ‘d’ 가 아닌 문자가 필요함

마지막 문장의 [] 처음에 있는 ^는 꺽쇄괄호 안에 지정한 문자를 제외한 나머지 문자를 말한다.   

연산자

이제 정규식의 동작 방식을 이해했을 것이다. 다음은 유용한 연산자들에 대한 내용이다.

정규식 연산자

a? a가 0개 혹은 1개 발생하면 일치 ‘a’ 나 빈 문자열
a* a가 0 혹은 그 이상 발생할 때 일치 빈 문자열이나 ‘a’, ‘aa’, ‘aaa’, 등
a+ a가 1번 이상 발생하면 일치‘a’, ‘aa’, ‘aaa’, 등
a|b a 나 b면 일치‘a’ 나 ‘b’
. 한개의 문자면 일치 ‘a’, ‘q’, ‘l’, ‘_’, ‘+’, 등
[woeirjsd] 지정한 문자들 중 하나 이면 일치 ‘w’, ‘o’, ‘e’, ‘i’, ‘r’, ‘j’, ‘s’, ‘d’
[1-9] 범위 안의 문자면 일치 ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’
[^13579] 지정한 문자 이외의 문자이면 일치 짝수 혹은 문자
(ie) 수식을 묶음 (다른 연산자와 사용하기 위함) ‘ie’
^a 줄의 맨 처음에 a가 있으면 일치‘a’
a$ 줄의 맨 끝에 a가 있으면 일치 ‘a’

 

?와 같이 위에 나와 있는 연산자를 실제 문자로 사용하려면 문자 앞에 ‘\’를 넣으면 된다.

// ?가 제일 끝에만 나오는 문장은 true
“How tall is Angelina Jolie?” ==~ /[^\?]+\?/

위 예는 가독성이 떨어진다. (PERL에서는 이렇게 많이 사용하는데 “write only” 언어로 여겨지는 이유 중의 하나이다.) 

그루비(Groovy) 튜토리얼 2 – 데이터로서의 코드 (클로저)

그루비(Groovy) 튜토리얼 2 - 데이터로서의 코드 (클로저)

2008.3.25 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+2+-+Code+as+data,+or+closures

 

클로저 (Closures)

대부분의 컴파일 언어와 그루비가 다른점의 하나는 고급 객체로 함수를 만들 수 있다는 것이다. 즉 여러 코드 집합을 정의하고 블록으로 감싸서 문자열이나 정수 처럼 사용할 수 있다. 다음 코드를 참고하기 바란다.

square = { it * it }

수식 “it * it” 사이를 중괄호로 묶으면 그루비 컴파일러가 수식을 코드로 간주한다. 컴퓨터공학에서는 이것을 클로저(closure)라고 한다. 이 경우에 지정자 “it”은 함수에 주어진 값을 참조한다. 그리고 나서 컴파일된 함수는 위에 나와 있는 바와 같이 변수 “square”에 값을 할당한다. 이제 다음과 같은 코드를 실행하면

square(9)

81 값이 나온다.

 

이런 방식은 함수 “square”를 값으로 전달할 수 있는지 찾지 못하면 흥미롭지 않다. 내장함수 중에서 함수가 인자인것 처럼 사용할 수 있는 것이 있다. 한 예로 배열에 대한 “collect” 메서드가 있다. 다음을 보자.

[ 1, 2, 3, 4 ].collect(square)

이 수식에서는 배열 1, 2, 3, 4를 만들고 “collect” 메서드를 호출하여 앞에서 정의한 클로저를 전달한다. collect 메서드는 배열의 각 값의 클로저를  호출하여 결과로 다음과 같이 새로운 배열을 만든다.

[ 1, 4, 9, 16 ]

인자로서 클로저를 호출하는 더 많은 메서드는 그루비 JDK(GDK) 문서를 참조하기 바란다.

 

기본적으로 클로저는 “it”이라는 파라메터를 하나 가지고 있으며 클로저에 다른 이름의 파라메터를 만들 수도 있다. 예를 들어 Map.each() 메서드는 키, 값 쌍으로 된 두개의 변수를 가진 클로저를 가져올 수 있다.

printMapClosure = { key, value -> println key + “=” + value }[ “yue” : “wu”, “lane” : “burks”, “sudha” : “saseethiaseeleethialeselan” ].each(printMapClosure)

결과:

yue=wulane=burkssudha=saseethiaseeleethialeselan
클로저 예제

다음 아래 코드는 클로저 예제이다. 첫번째는 두 가지 측면에 관심을 가져 보기 바란다. 첫째, 클로저가 밖에 있는 변수와 상호작용하고 있다. 즉 클로저가 fullString 변수에 orderParts 배열에서 만든 저장 순서를 추가로 붙여 하나의 문자열로 만들고 있다. fullString 변수는 클로저가 아니다. 둘째, 이 예제에서 특이한 점은 클로저가 익명(anonymous), 즉 이름이 없이 정의한 상태에서 each 메서드를 호출하고 있다. 

fullString = “”orderParts = [“BUY”, 200, “Hot Dogs”, “1”]orderParts.each {  fullString += it + ” “}println fullString
이 예제에서 출력하는 결과는 추측하기 쉬울 것이다.
다음 예제는 또다는 익명 클로저(anonymous closure)로서 맵에 저장한 값을 합산하는 것이다. 
myMap = [“asdf”: 1 , “qwer” : 2, “sdfg” : 10]result = 0myMap.keySet().each( { result+= myMap[it] } )println result
파일 처리
파일에서 데이터를 읽은 것은 비교적 간단하다. 우선 텍스트 파일 myfile.txt를 만들어 보자. 
안에 무것이 있건 상관없다. 간단한 내용을 채우고 C: emp에 저장한다. 그리고 groovyConsole에서
다음 코드를 입력해 본다.
myFileDirectory = “C:	emp”myFileName = “myfile.txt”myFile = new File(myFileDirectory + myFileName)printFileLine = { println “File line: “ + it }myFile.eachLine( printFileLine )

이 코드는 파일안의 각 라인이 “File line:” 접두어와 출력되어 나올 것이다. 
처음 두 라인은 파일 위치를 가리킨다. 두 변수명을 합쳐서 전체 경로를 만든다.
백슬래시 문자는 그루비에서 특수문자로 취급하므로 백슬래쉬 자체의미로 사용하고자 한다면
두 번 적어야 한다.
다음 라인은 “myFile =”로 시작하며 File 객체를 만든다. 객체는 메서드와 데이터로 구성된다. 
예를 들어 파일 객체는 “c: empmyFile.txt”와 같이 파일 위치를 가리키는 데이터와 파일이 있다면
삭제하는 메서드가 있을 것이다. 위 코드는 제일 마지막줄에 나와 있듯이 eachLine 메서드를 사용하는데
각 라인별로 간단한 클로저인 printFileLine가 호출된다. 
문자열 처리
그루비의 문자열은 자바 문자열와 같은 기능을 가지고 있다. 즉 그루비 문자열은 몇가지 기능이
추가된 자바 문자열이다. 따라서 궁금한 점은 String 클래스 자바 문서를 참고해도 된다. 예를 들어
메서드 요약(Method Summary)에서 “split” 메서드를 찾아보도록 하자. 이 메서드는 정규식
(regular expression)을 기반으로 문자열을 나누는 유용한 메서드이다. 정규식은 나중에 자세히 이야기
할 것이며 지금은 가장 간단한 정규식은 문자라는 것이다. 그래서 날짜 “2005-07-04″를 분리하여 1년을
증가시킨 7월 4일을 구해보기로 하자.
stringDate = “2005-07-04”dateArray = stringDate.split(“-“)year = dateArray[0].toInteger()year = year + 1newDate = year + “-“ + dateArray[1] + “-“ + dateArray[2]
위 코드는 앞에서 이야기한 내용이 들어 있으며 두가지 새로운 부분이 있다. 첫째, String에서 
split 메서드를 사용한 것. 둘째, String에서 toInteger()를 호출한 것이다. toInteger를 호출하면
그루비에서 데이터를 정수로 변환한다. “.toInteger()” 없이 실행하면 어떻게 되는지 직접 확인해보기
바란다.
또하나 유의할 사항은 toInteger는 문자열 자바 문서에는 들어 있지 않다. 그 이유는 이 부분은 
그루비에서 추가로 구현한 기능이기 때문이다. 그루비에서 확장한 자바 객체 문서를 참고하기 바란다.
 

그루비(Groovy) 튜토리얼 1 – 시작하기

그루비(Groovy) 튜토리얼 1 - 시작하기

2008.3.23 translation & editing by gilbird

원문: http://groovy.codehaus.org/Tutorial+1+-+Getting+started

 

시작하기 

자바 환경 설정

그루비는 자바를 사용한다. 따라서 최신버전의 자바를 미리 설치하기 바란다. 

자바를 아직 설치 하지 않았다면 다음 단계대로 하면 된다.

  • http://java.sun.com에서 최신 자바 설치 프로그램을 구한다.
  • 설치를 수행한다.
  • JAVA_HOME 환경 변수를 설정한다. 윈도우즈에서는 다음과 같이 한다.
    • 내 컴퓨터의 속성을 클릭한다.
    • 고급 탭의 환경 변수 버튼을 클릭한다.
    • 시스템 변수의 새로 만들기 버튼을 클릭하여 변수 이름은 JAVA_HOME,
      변수 값은 자바를 설치한 디렉토리명을 입력한다. (예: C:jdk1.6.0_05)

그루비 환경 설정

그루비 인스톨러를 다운로드 페이지에서 다운받고 안내에 따라서 설치한다.

 

추가적인 jar 파일 설정

추가적으로 그루비 모듈, 클래스 파일 등으로 구성된 jar 파일을 받고자 한다면, 다음 링크를 참고하기 바란다.

 

Name From Description
jtds-version.jar http://jtds.sourceforge.net Database driver for SQL Server and/or Sybase
hsqldb-version.jar http://www.hsqldb.org/ Database driver for HSQLDB, a 100% Java database

 

그루비에서 추가한 jar 파일을 인식할 수 있도록 미리 정의한 위치에 두도록 한다. 그루비 설치시 groovy-starter.conf 파일이 생기는데 파일을 열어보면

load ${user.home}/.groovy/lib/*

을 볼 수 있을 것이다. user.home 시스템 속성은 운영체제에서 설정한 것이다. 따라서 jar 파일은 사용자 홈디렉토리의  .groovy/lib 디렉토리(예: C:Documents and Settingsgilbird.groovylib)에 두기 바란다.

 

Hello, World

groovyConsole의 상단 창에서 다음을 입력하라.

println “Hello, World!”

그리고 <CTRL+R> 혹은 <CTRL+ENTER>를 누른다.

groovyConsole 창 하단에서 텍스트가 나오는 것을 확인 하면 다음과 같이 나온다.

그루비(Groovy) 튜토리얼 1 - 시작하기


다음은 산술식을 입력해보자.

123+45*67

위와 같은 산술식을 입력하여 <CTRL+R>을 입력하면 연산 결과가 나옴을 알 수 있다.

 

그루비(Groovy) 튜토리얼 1 - 시작하기

 

변수

변수에 값을 저장하여 나중에 사용할 수 있다. 다음 코드를 실행해보라.

x = 1println xx = new java.util.Date()println xx = -3.1499392println xx = falseprintln xx = “Hi”println x

리스트와 맵

그루비에서는 두가지 중요한 내장 데이터 타입으로 리스트와 맵을 지원한다 (리스트는 자바 언어의 배열처럼 사용할 수 있다). 리스트는 순서있는 데이터를 저장할 때 사용한다. 예를 들어 정수 리스트는 다음과 같다.

myList = [1776, -1, 33, 99, 0, 928734928763]
리스트값은 각괄호 표현으로 액세스한다. (인덱스는 0부터 시작)
println myList[0]
위의 결과값은 1776이 나와야 한다.
리스트 길이는 “size” 메서드로 구한다.
println myList.size()
위의 결과값은 6이 나와야 한다.

그러나 일반적으로 길이값은 필요가 없다. 그 이유는 자바와 달리 “each” 메서드를 사용하면 모든 엘리먼트를 액세스하는 루프를 만들 수 있는데 “데이터로서의 코드(클로저)번역“절에서 세부적으로 다룬다.

 

또 다른 내장 데이터 형식으로 맵이 있다. 맵은 연상 배열(associative array)와 사전(dictionary)을 저장하는데 사용한다. 맵은 순서가 없는 이종의 이름 데이터이다. 예를 들어 이름과 IQ점수를 저장하고 싶다면 다음과 같이 하면 된다.

scores = [ “Brett”:100, “Pete”:“Did not finish”, “Andrew”:86.87934 ]

맵에 저장한 각 값의 형식이 다름에 주목하기 바란다. Brett의 값은 정수, Pete의 값은 문자열, Adrew의 값은 부동 소숫점수이다. 맵의 값은 두가지 방식으로 액세스 할 수 있다.

println scores[“Pete”]println scores.Pete

위 결의 결과는 다음과 같다.

Did not finishDid not finish

데이터를 추가는 리스트에 값을 추가하는 것과 비슷하다. 예를 들어, Pete가 IQ 테스트를 다시 받아 3을 받았다면 다음과 같이 할 수 있다.

scores[“Pete”] = 3

위의 값을 다시 액세스하면 3이 나와야 한다.

println scores[“Pete”]

또한 다음과 같이 빈 리스트나 맵도 만들 수 있다.

emptyMap = [:]emptyList = []
데이터가 비어 있는지 확인하려면 “size” 메서드로 값이 0 인지 확인한다.
println emptyMap.size()println emptyList.size()

 

조건 실행 (Conditional Execution)

프로그래밍 언어의 가장 중요한 특징 중의 하나는 여러 조건에 따라서 각각 알맞은 코드를 수행하는 것이다. “if”문을 사용하면 제일 간단하게 조건문을 만들 수 있다.

amPM = Calendar.getInstance().get(Calendar.AM_PM)if (amPM == Calendar.AM){println(“Good morning”)} else {println(“Good evening”)}

첫번째 라인은 현재 시간이 오전인지 오후인지 알아내는 코드라는 것만 알고 넘어가자. 나머지 코드는 다음과 같이 실행한다: 1) 괄호안의 수식을 비교한다. 그리고 결과가 “true”인지 “false”인지에 따라서 첫번째나 두번째 코드 블록을 실행한다. 아래에 있는 논리식을 참고하기 바란다.

 

“else” 블록은 없어도 되지만 “then” 블록은 꼭 있어야 한다.

amPM = Calendar.getInstance().get(Calendar.AM_PM)if (amPM == Calendar.AM){println(“Have another cup of coffee.”)}
논리식 (Boolean Expression)

대부분의 프로그래밍 언어에는 “true”와 “false”를 표현하는데 사용하는 특별한 데이터 형식이 있다. 가장 간단한 논리식은 true, false값 자체이다. 논리값은 다른 데이터 형식과 마찬가지로 변수에 저장할 수 있다.

myBooleanVariable = true

보다 복잡한 논리식은 다음 논리연산자 중에서 하나를 사용하는 것이다.

* ==* !=* >* >=* <* <=

위에서 나오는 논리 연산자 대부분은 직관적이다. 동등연산자(equality operator)는 할당연산자(assignment operator) “=”와 구별하기 위하여 “==”로 사용하며 동등의 반대는 “!=” 연산자로서 같지 않다는 뜻이다.

 

다음은 논리 연산자 예제이다.

titanicBoxOffice = 1234600000titanicDirector = “James Cameron”trueLiesBoxOffice = 219000000trueLiesDirector = “James Cameron”returnOfTheKingBoxOffice = 752200000returnOfTheKingDirector = “Peter Jackson”theTwoTowersBoxOffice = 581200000theTwoTowersDirector = “PeterJackson”titanicBoxOffice > returnOfTheKingBoxOffice  // evaluates to truetitanicBoxOffice >= returnOfTheKingBoxOffice // evaluates to truetitanicBoxOffice >= titanicBoxOffice         // evaulates to truetitanicBoxOffice > titanicBoxOffice          // evaulates to falsetitanicBoxOffice + trueLiesBoxOffice < returnOfTheKingBoxOffice + theTwoTowersBoxOffice  // evaluates to falsetitanicDirector > returnOfTheKingDirector    // evaluates to false, because “J” is before “P”titanicDirector < returnOfTheKingDirector    // evaluates to truetitanicDirector >= “James Cameron”           // evaluates to truetitanicDirector == “James Cameron”           // evaluates to true

특히 논리식은 “if” 문과 같이 사용하면 유용하다. 예를 들면:

if (titanicBoxOffice + trueLiesBoxOffice > returnOfTheKingBoxOffice + theTwoTowersBoxOffice){println(titanicDirector + ” is a better director than “ + returnOfTheKingDirector)}

특별히 유용한 테스트는 변수나 수식이 null (값이 없음)인지 체크하는 것이다. 예를 들어 맵안에 제시한 키의 값을 보고 싶다고 하자.

suvMap = [“Acura MDX”:“$36,700”, “Ford Explorer”:“$26,845”]if (suvMap[“Hummer H3”] != null){ println(“A Hummer H3 will set you back “+suvMap[“Hummer H3”]);}

일반적으로 null로 특정 위치의 값이 비어있는지를 가리킨다.

 

디버깅과 해결팁

  • myVar.getClass()로 관심있는 변수의 클래스가 무엇인지 출력한다. 그리고 해당 클래스를 문서를 본다.
  • 복잡한 수식에 문제가 생기면 단순한 수식으로 쪼개내어 분석한다.
  • groovyConsole을 재시작 해본다 (처음부터 시작할 수 있도록 모든 변수를 제거할 것이다).
  • 그루비 사용자 가이드에서 관심있는 주제를 찾아 보기 바란다.

자바 개발자라면

  • 자바와의 차이점을 알고 싶을 것이다.
  • 그리고 주의할 사항도 알고 싶을 것이다.