17 stycznia 2009

Kolekcje w "Groovy Basics" z Beginning Groovy and Grails

Kolejna odsłona lektury książki Beginning Groovy and Grails: From Novice to Professional. Dokończyłem rozdział 2 "Groovy Basics" i czuję się już cały gotowy, aby podjąć się jakiegoś wyzwania w Groovy. Nie wiem, co mogłoby to być, ale od kiedy zacząłem przyglądać się temu językowi i Grails wokół mnie coraz więcej informacji o nich. Jedni zachwyceni i pytają, czego nie można zrobić w Groovy - Bruce Eckel asks "What can't Grails do?", a drudzy wręcz przeciwnie - zniechęceni i wręcz zdegustowani przesadną ich reklamą - Nowy rok … stare marzenia :).

Skoro o tworzeniu aplikacji z parą Groovy/Grails to zapewne niejeden zastanawiał się, w czym to cudo poznawać - przydałoby się jakieś IDE (zintegrowane środowisko programistyczne). Ostatnio głośno o tym było na grupie dyskusyjnej użytkowników Grails - Best IDE for grails development, a wystarczy wpisać w Google "grails best ide" i od razu można zorientować się, że temat niezwykle gorący. Osobiście do tej pory próbowałem się jedynie z NetBeans IDE 6.5 i przyznaję, że największym mankamentem było dla mnie ciągła konieczność zatrzymywania serwera, aby móc wdrożyć zmiany. Bez tego zmiany nie były rozpoznawane. Mam w odwodzie IntelliJ IDEA 8 i od dzisiaj jej się przyjrzę (dla tych, którzy nie mają, a chcieliby przypomnę, że wystarczy wystąpić z prezentacją na jednym z lokalnych JUGów i licencja na rok gwarantowana).

Kończąc rozdział 2 "Groovy Basics" jeszcze raz zerknąłem na sekcję o domknięciach. W wolnym tłumaczeniu to po prostu metoda bez nazwy i zwracanego typu. Wszystko inne jest oraz domknięcie to obiekt w Groovy. To już było wczoraj, ale o czym nie wspomniałem, to właśnie parametry. Tak, domknięcia mogą mieć parametry wejściowe, np.
 def domkniecie = { parametrWejsciowy -> println "Parametr wejsciowy to ${parametrWejsciowy}" }
i wystarczy wywołać podając parametr z lub bez nawiasów (przy bezparametrowym wywołaniu nawiasy są obowiązkowe):
 domkniecie "Prezentacja domknięcia w Groovy"
Jeszcze nie rozumiem, dlaczego deklaracja domknięcia domkniecie z def w powłoce groovysh kończy się ERROR groovy.lang.MissingMethodException: No signature of method: groovysh_evaluate.domkniecie() is applicable for..., ale to później.

Kolej na przegląd typów zbiorowych - kolekcji. Mamy listy, zakresy, zbiory, tablice i mapy. W zasadzie podobnie jak w Javie, poza zakresem. Różnica między kolekcjami w Groovy, a w Javie to ich deklaracja. Zawsze można skorzystać z new <nazwa_typu_z_Javy>, np. new ArrayList(), ale kto by tak pisał w Groovy, skoro można trochę bardziej szałowo (ang. groovy). Jako pierwszą z kolekcji opisano listę. Lista w Groovy jest de facto egzemplarzem java.util.List i tworzymy ją nawiasami kwadratowymi
 def lista = []
Na moment pojawia się wzmianka o przeciążaniu operatorów (dobrze znane programistom C++), gdzie przedstawiono dodawanie i odejmowanie elementów z listy, odpowiednio, operatorami -= oraz +=.

Kolejnym typem zbiorowym jest zakres (ang. range), niedostępny programistom javowym. Jest to typ, w którym egzemplarze deklarowane są przez .., który oznacza "kolejne wartości w pewnym porządku", np.
 def cyfry = 0..9
Zakres jest po prostu pewną listą obiektów implementujących java.lang.Comparable. Interesującą konstrukcją jest użycie zakresu z < (znak mniejszości), co oznacza prawy otwarty koniec zbioru elementów, np.
 def cyfryInaczej = 0..<10
Jest to równoważne z deklaracją cyfry. Istnieje również możliwość odwrócenia kolejności, np.
 def cyfryMalejaco = 9..0
Następnie sekcja o zbiorach, które są, podobnie jak w Javie, nieuporządkowaną kolekcją obiektów bez duplikatów. Deklaracja odbywa się jak deklaracja listy z frazą as Set, np.
 def zbiorPusty = [] as Set
Domyślnie "pod spodem" będzie javowy java.util.HashSet. Wystarczy skorzystać z konstrukcji new <inny_rodzaj_zbioru>, aby otrzymać egzemplarz innego typu zbioru. Istnieje konstrukcja as List, aby ze zbioru stworzyć listę.

Dalej mamy przedstawiony typ tablicowy - tablicę, która jest sekwencją obiektów, jak w Javie. Konstrukcja tablicy to po prostu
 def tablica = new String[3]
Na zakończenie sekcji o kolekcjach przedstawiony jest typ mapa - nieuporządkowana kolekcja par klucz/wartość, w której klucz jest unikatowy. Jest to implementacja javowego java.util.Map i deklarowana jest przez nawiasy klamrowe z parami z dwukropkiem oddzielone przecinkiem. Domyślnie będzie to java.util.LinkedHashMap.
 def pustaMapa = [:]
def mapaZDwomaElementami = ["java":"Dobra sprawdzona", "groovy":"Potencjalnie dobry, właśnie sprawdzany"]
Ciekawostką map w Groovy jest możliwość przypisania wartości do klucza przez
 mapaZDwomaElementami.java = "Tylko dobra?! Jest wspaniała!"
Na koniec pojawia się sekcja o wyrażeniach regularnych. Potężne narzędzie, ale o nim w kolejnej odsłonie. Warto już teraz popróbować się z dotychczasową wiedzą o Groovy w powłoce Groovy - groovysh.
 C:\Documents and Settings\jlaskowski
> groovysh
Groovy Shell (1.6-RC-1, JVM: 1.6.0_11)
Type 'help' or '\h' for help.
--------------------------------------------------
groovy:000> println "I jak, podoba się Groovy?"
I jak, podoba się Groovy?
===> null
p.s. Ten blog uczestniczy w konkursie Blog Roku 2008. Wystarczy wysłać SMSa o treści B00204 (czytaj: be-zero-zero-dwa-zero-cztery) pod numer 7144 za 1,22PLN brutto i ma się zapewnioną wdzięczność blogera Jacka ;-)