<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5791022022546268432</id><updated>2011-07-08T12:40:39.334+02:00</updated><category term='toolbox'/><category term='przegadane'/><category term='C++'/><category term='Python'/><category term='CDT'/><category term='Scala'/><category term='blogger'/><category term='Ruby'/><category term='Eclipse'/><category term='AppEngine'/><category term='Hibernate'/><category term='metodyki'/><category term='Java'/><category term='LaTeX'/><category term='Groovy'/><category term='ogólne'/><title type='text'>Krzysiek vs. IT</title><subtitle type='html'>Zawsze znajdzie się właściwy klucz, żeby dobić śrubę.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-8118526757915551776</id><published>2010-01-26T23:08:00.005+01:00</published><updated>2010-01-26T23:25:09.860+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Sprawdź to szybko z @Grapes</title><content type='html'>W książce o Hibernate (którą sobie czytam) piszą, że uruchomienie Hibernate jest ciężkie i paskudne, bo trzeba dużo bibliotek zebrać, wrzucić na classpath i to wszystko skonfigurować. No, kilka ich jest. Jeszcze trzeba znaleźć w Internecie paczkę, ściągnąć, wybrać wymagane pliki itp. Wybrać jakąś bazę danych&lt;br /&gt;&lt;br /&gt;To jest mało wygodne. To może maven? Hm, sprawdzam, integracja z Eclipse dalej leży choć wyraźnie się poprawiła w ostatnim roku, na Idea brak miejsca, Netbeans nie lubie. Hm, jeszcze jest Ivy...&lt;br /&gt;&lt;br /&gt;Po analizie różnych rozwiązań, za najprostsze uznałem &lt;a href="http://groovy.codehaus.org/Grape"&gt;Grape&lt;/a&gt;. Grape to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Deklaratywne zarządzanie zależnościami za pomocą adnotacji (@Grab).&lt;/li&gt;&lt;li&gt;To co potrzeba zostanie ściągnięte do lokalnego repozytorium i dorzucone do classpath w trakcie uruchamiania skryptu / klasy.&lt;/li&gt;&lt;li&gt;Obsługa linii poleceń – (grape install &amp;lt;groupid&gt; &amp;lt;artifactid&gt; [&amp;lt;version&gt;])&lt;/li&gt;&lt;li&gt;Nic nie trzeba instalować jeśli ma się Groovy&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Wystarczy deklaratywnie napisać czego nam potrzeba . Grape korzysta z Ivy, więc mamy dostęp do całego dobrodziejstwa znanego z repozytoriów Maven. Przykład z Hibernate:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package hello;&lt;br /&gt;&lt;br /&gt;import javax.persistence.*;&lt;br /&gt;import org.hibernate.*;&lt;br /&gt;import org.hibernate.cfg.*;&lt;br /&gt;&lt;br /&gt;//Wymagane zaleznosci:&lt;br /&gt;@Grapes([&lt;br /&gt; @Grab(group='org.hibernate', module='hibernate-annotations', version='3.4.0.GA'),&lt;br /&gt; @Grab(group='hsqldb', module='hsqldb', version='1.8.0.7'),&lt;br /&gt; //niestety slf4j i javaassist trzeba dodać ręcznie bo w POM są pewnie jako opcjonalne (lub wcale), ale domyślnie wybierane przez Hibernate&lt;br /&gt; @Grab(group='org.slf4j', module='slf4j-simple', version='1.4.2'), &lt;br /&gt; @Grab(group='javassist', module='javassist', version='3.4.GA')&lt;br /&gt;])&lt;br /&gt;@Entity &lt;br /&gt;class Book{&lt;br /&gt; @Id @GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt; Long id&lt;br /&gt; String title&lt;br /&gt; String author&lt;br /&gt; String toString(){ "$title by $author" }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def prepareSessionFactory(){&lt;br /&gt; def config = new AnnotationConfiguration()&lt;br /&gt; [&lt;br /&gt;  "hibernate.dialect": "org.hibernate.dialect.HSQLDialect",&lt;br /&gt;  "hibernate.connection.driver_class": "org.hsqldb.jdbcDriver",&lt;br /&gt;  "hibernate.connection.url": "jdbc:hsqldb:mem:demodb",&lt;br /&gt;  "hibernate.connection.username": "sa",&lt;br /&gt;  "hibernate.connection.password": "",&lt;br /&gt;  "hibernate.hbm2ddl.auto": "create-drop",&lt;br /&gt;  "hibernate.show_sql": "true",&lt;br /&gt;  "hibernate.current_session_context_class": "thread"&lt;br /&gt; ].each{ key, value -&gt; config.setProperty (key, value)}&lt;br /&gt; &lt;br /&gt; config.addAnnotatedClass(Book)&lt;br /&gt; config.buildSessionFactory()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def session = prepareSessionFactory().openSession();&lt;br /&gt;Transaction tx = null;&lt;br /&gt;try{&lt;br /&gt; &lt;br /&gt; tx = session.beginTransaction()&lt;br /&gt; def b = new Book(title:"Narrenturm",author:"Sapkowski")&lt;br /&gt; session.persist b&lt;br /&gt; tx.commit()&lt;br /&gt; &lt;br /&gt; tx = session.beginTransaction()&lt;br /&gt; Book b2 = session.createQuery("From Book").list().first()&lt;br /&gt; println b2&lt;br /&gt; tx = null&lt;br /&gt; &lt;br /&gt;}catch(HibernateException e){&lt;br /&gt; if(tx != null) tx.rollback()&lt;br /&gt; println e&lt;br /&gt;}finally{&lt;br /&gt; session.close()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Uruchamiam z poziomu Eclipse, można też wrzucić do GroovyConsole i uruchomić, wszystkie wymagane biblioteki powinny się ściągnąć same, przykład ze strony Groovy mi dział, a ten nie... To znaczy ściąganie działa, ale Hibernate nie. Z poziomu Eclipse mi to działa, z GroovyConsole wyskakuje za to błąd dostępu do pól, ciekawe... Pewnie kwestia generowania kodu. Na razie działające Eclipse z podpowiadaniem kodu mi wystarcza, no i mały skrypt co kopiuje wszystkie biblioteki ściągnięte przez Grapes do Eclipse ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-8118526757915551776?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/8118526757915551776/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=8118526757915551776' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/8118526757915551776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/8118526757915551776'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2010/01/sprawdz-to-szybko-z-grapes.html' title='Sprawdź to szybko z @Grapes'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7940097600668743347</id><published>2010-01-26T15:29:00.001+01:00</published><updated>2010-01-26T15:29:47.114+01:00</updated><title type='text'>Update</title><content type='html'>&lt;p&gt;No i minęło p&amp;#243;ł roku od ostatniego wpisu. W między czasie skończyłem studia w Polsce, pojechałem do Szwecji, tam właściwie też studia skończyłem, wr&amp;#243;ciłem, chwila odpoczynku, zachorowałem i wylądowałem na 3 antybiotykach... Teraz się doleczam i myślę, że najwyższa pora wr&amp;#243;cić do tak zwanej &amp;quot;rzeczywistości&amp;quot;.&lt;/p&gt;  &lt;p&gt;Pracę magisterską oceniono mi na 5, a ja uważam ją za osobistą porażkę. Zabawa trwała za długo i za dużo mnie kosztowała. Przez ostatnie mniej więcej 1,5 roku zajmowałem się zabawkami na ogromnym poziomie abstrakcji. W Polsce znam tylko jedno miejsce gdzie korzystają z tych samych zabawek ale do czego innego (z pozdrowieniami dla Grześka ;) ). Praca w tym też jest tylko, że w Niemczech, Francji, Kanadzie ;) Po wstępnych badaniu kogo szukają we Francji ostatecznie stwierdziłem, że na razie nie chce wyjeżdżać. &lt;/p&gt;  &lt;p&gt;To z kolei oznacza, że pora przypomnieć sobie Hibernate, nauczyć Spring itp.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7940097600668743347?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7940097600668743347/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7940097600668743347' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7940097600668743347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7940097600668743347'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2010/01/update.html' title='Update'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-9139550552333507267</id><published>2009-07-31T21:04:00.001+02:00</published><updated>2009-07-31T21:04:59.668+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='przegadane'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Revenge of the Modelers !</title><content type='html'>&lt;p&gt;Jeśli nie lubicie modelowania to mam dla was złe wiadomości&amp;#8230; poniżej. Najpierw małą dygresja.&lt;/p&gt;  &lt;p&gt;Wakacje wakacjami, jednak przygoda z Erasmusem kończy się dla mnie ich brakiem (przynajmniej do września). Szkoda, bo dzieje się dużo. Moda na nowe języki jak Groovy, Scala czy nawet Clojure jest w pełni... I choć uważam Scala za nie najlepszy język to i tak pewnie będę się go uczył bo    &lt;br /&gt;a) jest statycznie typowany z inferencją typ&amp;#243;w i domknięciami     &lt;br /&gt;b) Java 1.7 domknięć nie będzie mieć     &lt;br /&gt;c) Groovy jest wyłącznie dynamicznie typowany     &lt;br /&gt;d) Fan jest fajny, ale stara się za bardzo być wieloplatformowy, a ja chcę po prostu lepszą Java, chociaż...&lt;/p&gt;  &lt;p&gt;No i dalej nie ma dobrego języka na JVM! &lt;/p&gt;  &lt;p&gt;Ps.:   &lt;br /&gt;Lepsze wsparcie dla Groovy w Eclipse    &lt;br /&gt;&lt;a href="http://blog.springsource.com/2009/07/30/a-groovier-eclipse-experience/"&gt;http://blog.springsource.com/2009/07/30/a-&lt;b&gt;groovier&lt;/b&gt;-eclipse-experience/&lt;/a&gt;    &lt;br /&gt;Cywilizowane wymienienie czym Fan się wyr&amp;#243;żnia    &lt;br /&gt;&lt;a href="http://fandev.org/sidewalk/topic/675"&gt;http://fandev.org/sidewalk/topic/675&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Wracając do tematu, &lt;/strong&gt;    &lt;br /&gt;Jakiś czas temu wyszedł Eclipse 3.5 - &lt;a href="http://eclipse.org/galileo/projects.php"&gt;http://eclipse.org/galileo/projects.php&lt;/a&gt;. Jeśli ktoś przeglądnie listę projekt&amp;#243;w, to zauważy 17 link&amp;#243;w do projekt&amp;#243;w związanych ściśle z modelowaniem. W Galileo mamy nowe wersje między innymi: Acceleo, ATL, EMF, CDO, JET2, GMF, OCL, Net4J, UML2, Teneo, QVTo, Xpand i Xtext. To nie wszystkie ciekawe projekty z działu modelowanie.&lt;/p&gt;  &lt;p&gt;Przyszły &lt;strong&gt;Eclipse 4&lt;/strong&gt; jest w całości oparty na modelach, wersja alfa (e4 0.9) jest dostępna do test&amp;#243;w. E4 to między innym model Workbench (perspektywy, komendy, okienka, to wszystko jest modelem, kt&amp;#243;ry można w dowolnym momencie zmienić), deklaratywne SWT -&amp;gt; XWT (taki odpowiednik HTML ale dla SWT, czyli kopia XAML), port SWT na Flash(Flex właściwie) ze wsparciem Draw2D więc, definiowanie wyglądu aplikacji SWT za pomocą CSS, wsparcie dla &amp;quot;dowolnego&amp;quot; języka przy pisaniu plugin&amp;#243;w (JavaScript z pudełka), wsparcie dla DI wbudowane w platformę. Nowa platforma ma też zmiany w swoich wnętrznościach i właściwie nie widzi r&amp;#243;żnicy w tym, czy działa przez web, czy działa stacjonarnie, czy lokalnie, czy rozproszona :)    &lt;br /&gt;&lt;a href="http://download.eclipse.org/e4/downloads/drops/R-0.9-200907291930/e4-news-all.html"&gt;http://download.eclipse.org/e4/downloads/drops/R-0.9-200907291930/e4-news-all.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Eh, i pojawia się problem - coraz więcej projekt&amp;#243;w Eclipse jest oparta lub wykorzystuje EMF (Eclipse Modeling Framework), a&amp;#160; jest spory problem w tłumaczeniu co ta biblioteka właściwie robi. Nawet jej tw&amp;#243;rcy nie bardzo wiedzą jak ją sprzedać. No bo jeśli powiem komuś, że jest to meta metamodel z mapowaniami do Java(generacja kodu), XML Schema i UML to    &lt;br /&gt;a) przesadnie uproszczę temat i pominę dużo    &lt;br /&gt;b) słuchający ucieknie z krzykiem jak usłyszy &amp;quot;meta metamodel&amp;quot; i &amp;quot;generacja kodu&amp;quot;&lt;/p&gt;  &lt;p&gt;Modele już nie czają się w krzakach. One atakują. Nowe projekty jak Microsoft Oslo i Quadrant, Eclipse Modeling Framework z Xtext i starym GMF, czy JetBrains MPS znalazły nową broń marketingową - DSL.&lt;/p&gt;  &lt;p&gt;EMF nie zna litości, gdy ma się stworzony model, to nie dość, że można go bez problemu zapisać w pliku XML o dość dowolnej strukturze, to można go zapisać w pliku XMI, kt&amp;#243;ry każde narzędzie wspierające EMF potrafi otworzyć i edytować. Co gorsza taki model może być zapisany w zwykłym pliku tekstowym(XText), kt&amp;#243;ry wygląda jak nie pozorny język lub konfiguracja i jest czytelniejszy niż kod albo XML! Może też być obrazkiem jak diagram klas, albo encji(GMF). EMF r&amp;#243;wnież kpi sobie z baz danych i pozwala bez dodatkowej pracy się w nich przetrzymywać (Teneo, CDO),&amp;#160; jeśli chce to nawet można zmienić zasady zapisu do bazy danych za pomocą Hibernate lub EclipseLink i ich mapowań. EMF ignoruje fakt, że pamięć jest ograniczona, a użytkownicy rozproszeni. Pozwala pracować na modelach większych niż dostępny ram, na dodatek w dowolnej lokalizacji, wielu użytkownikom r&amp;#243;wnocześnie (CDO). Aplikacja E4 RCP mogłaby mieć model UI trzymany na serwerze i wtedy można by go zdalnie zmienić, a wszyscy użytkownicy systemu natychmiast mogli by zobaczyć zmiany w swoim interfejsie! &lt;/p&gt;  &lt;p&gt;Ciężkie czasy idą ;)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-9139550552333507267?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/9139550552333507267/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=9139550552333507267' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/9139550552333507267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/9139550552333507267'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2009/07/revenge-of-modelers.html' title='Revenge of the Modelers !'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-5886938677610162780</id><published>2009-04-20T14:58:00.003+02:00</published><updated>2009-04-20T15:13:55.663+02:00</updated><title type='text'>Oracle = Java</title><content type='html'>Oracle kupił SUN - &lt;a href="http://www.sun.com/third-party/global/oracle/index.jsp"&gt;http://www.sun.com/third-party/global/oracle/index.jsp&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hm, no to jedna firma kontroluje bazy danych - Oracle i MySQL. To co teraz z DB2 zrobi IBM? MS SQL da sobie jakoś radę.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pojawia się kilka zabawnych konfliktów, do rozwiązania:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Oracle nie wydaje mi się firmą sprzętową&lt;/li&gt;&lt;li&gt;Solaris i Linux, może Oracle przestanie kopiować RedHat Linux?&lt;/li&gt;&lt;li&gt;Netbeans, JDeveloper i Eclipse. Oracle sam komituje sporo do Eclipse (EclipseLink, WebTools), a po kupnie BEA posiada komercyjne IDE oparte na Eclipse więc przewiduje dalszą migracje do Eclipse.&lt;/li&gt;&lt;li&gt;JavaFx, JavaMe i Oracle? Brzmi dziwnie.&lt;/li&gt;&lt;li&gt;Glassfish i Bea WebLogic.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Dobrze zapowiada się rozwój JSF jak i JVM. Mam nadzieje, że Oracle docenia nowe języki jak Groovy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;No to teraz IBM powinien też kupić coś ciekawego, może SpringSource albo RedHat?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ps. No to oczekuje teraz Oracle PaaS albo Oracle Cloud Database etc.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-5886938677610162780?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/5886938677610162780/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=5886938677610162780' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/5886938677610162780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/5886938677610162780'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2009/04/oracle-java.html' title='Oracle = Java'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-429393203969356123</id><published>2009-04-08T09:46:00.003+02:00</published><updated>2009-04-08T10:48:19.240+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AppEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Google App Engine + Java, Groovy...</title><content type='html'>Zgodnie z przewidywaniami Java jest już obsługiwana przez App Engine, na razie dla wybranych.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html"&gt;http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;a najlepsze w tym jest oczywiście&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://blog.springsource.com/2009/04/07/write-your-google-app-engine-applications-in-groovy/"&gt;http://blog.springsource.com/2009/04/07/write-your-google-app-engine-applications-in-groovy/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Grails jeszcze nie działa.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ogólnie mamy &lt;a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine"&gt;http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;W praktyce nowe obsługiwane języki to Groovy, Scala, Jytho, JRuby i Rails, JavaScript(Rhino)!&lt;/div&gt;&lt;div&gt;I po co w ogóle zaczynali samego Python-a? Nie ma praktycznie potrzeby dodawać już innych jezyków, wystarczy popracować nad wsparciem Java.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Odnośnie samej Java to:&lt;/div&gt;&lt;div&gt;Servlety 2.4, JSP, JSTL, JPA, JDO, Java Mail...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nie wiadomo co z JSF, Spring działa częściowo, Struts nie działa, Hibernate i podobne również nie. Może takie projekty jak Seam zajmą się wsparciem GAE.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Przy okazji Groovy, polecam artykuł &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.codethinked.com/post/2009/04/05/Do-We-Create-Type-Systems-In-Dynamic-Languages.aspx"&gt;http://www.codethinked.com/post/2009/04/05/Do-We-Create-Type-Systems-In-Dynamic-Languages.aspx&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Moim zdaniem to działa w dwie strony. W językach dynamicznie typowanych tworzymy w testach coś co w dużej mierze sprawdza nam typy i mimo,  że sprawdza je dynamicznie, to i tak pewna część kodu nie była by potrzebna. Nie widać tego, bo języki dynamiczne mają przeważnie ciekawszą składnie. Z drugiej strony w językach statycznie typowanych wdrażamy przeważnie dynamizm "kodując" w String-ach.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Groovy i Scala i C# 4 to ciekawe przykłady zmian. W Groovy można opisywać typy, ale dalej nie jest to statyczna typizacja. Scala jest statycznie typowana ale z silnym odkrywaniem typów. Ma dodatkowo składnie równie silną jak w językach dynamicznych (choć trochę przegieli) .&lt;/div&gt;&lt;div&gt;C# 4 to język silnie typowany z możliwym odkrywaniem typów i typami anonimowaymi (wszystko to plus lambda wyrażenia i budowa drzew składni jest potrzebne by LINQ mógł istnieć). Dodatkowo od wersj 4 będzie można powiedzieć, że wybrany element jest "dynamiczny"...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx" style="text-decoration: none;"&gt;http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-429393203969356123?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/429393203969356123/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=429393203969356123' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/429393203969356123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/429393203969356123'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2009/04/google-app-engine-java.html' title='Google App Engine + Java, Groovy...'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7554502543372892387</id><published>2009-03-14T21:59:00.002+01:00</published><updated>2009-03-14T22:05:28.187+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='toolbox'/><title type='text'>Dropbox - kontrola wersji dla nie programistów</title><content type='html'>&lt;p&gt;Systemy kontroli wersji są dobre, są też w pełni darmowe &lt;a href="http://xp-dev.com/"&gt;http://xp-dev.com&lt;/a&gt; i prawie darmowe &lt;a href="http://assembla.com/"&gt;http://assembla.com&lt;/a&gt; rozwiązania. &lt;/p&gt;&lt;p&gt;Jednak ludzie spoza IT z nie znanych mi powodód SVN nie akceptują ;)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dropbox&lt;/strong&gt; to aplikacja która pozwala na &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;synchronizowanie&lt;/span&gt; danego folderu między &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;wieloma komputerami&lt;/span&gt; wraz z &lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;kopią w internecie&lt;/span&gt;. Darmowa wersja pozwala na przechowywanie 2 gb danych i trzyma historię ich zmian.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GEH0YpYIgzE/Sbwal60NiuI/AAAAAAAAAXo/50zrMF53gdw/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="387" alt="image" src="http://lh4.ggpht.com/_GEH0YpYIgzE/SbwamcJGmsI/AAAAAAAAAXs/DwIiPreDWZU/image_thumb%5B2%5D.png?imgmax=800" width="585" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Dropbox pozwala na współdzielenie folderów (ludziki na folderze Magisterka), udostępnianie folderu publicznie w internecie (jak również widać na rysunku) i teoretycznie działa na Windows, Linux i Mac. &lt;/p&gt;  &lt;p&gt;Wystarczy zapisać dowolny plik w odpowiednim folderze, a ten automatycznie zostanie wysłany do internetu i synchronizowany z zarejestrowanymi komputerami.&lt;/p&gt;  &lt;p&gt;W internecie możemy przeglądać pliki (włącznie z ich historią)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_GEH0YpYIgzE/Sbwam7M8HxI/AAAAAAAAAXw/ogPXz09lSbQ/s1600-h/image%5B10%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="386" alt="image" src="http://lh6.ggpht.com/_GEH0YpYIgzE/Sbwanid7WbI/AAAAAAAAAX0/zqD5nlKaE28/image_thumb%5B6%5D.png?imgmax=800" width="593" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; A zdjęcia są dostępne w postaci galerii, którą również można opublikować&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_GEH0YpYIgzE/SbwaoBBs18I/AAAAAAAAAX4/1KouHGNOu5c/s1600-h/image%5B15%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="273" alt="image" src="http://lh3.ggpht.com/_GEH0YpYIgzE/SbwapGVapRI/AAAAAAAAAX8/cH9eZvZ8tlQ/image_thumb%5B9%5D.png?imgmax=800" width="599" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Można uzyskać dodatkowe 250 MB dla siebie (i dla mnie) korzystając z tego linku:&lt;/p&gt;  &lt;p&gt;  &lt;a href="https://www.getdropbox.com/referrals/NTQ4NDY0Mzk"&gt;https://www.getdropbox.com/referrals/NTQ4NDY0Mzk&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7554502543372892387?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7554502543372892387/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7554502543372892387' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7554502543372892387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7554502543372892387'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2009/03/dropbox-kontrola-wersji-dla-nie.html' title='Dropbox - kontrola wersji dla nie programistów'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_GEH0YpYIgzE/SbwamcJGmsI/AAAAAAAAAXs/DwIiPreDWZU/s72-c/image_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-184563023920033831</id><published>2009-03-10T15:10:00.002+01:00</published><updated>2009-03-10T15:12:38.366+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='CDT'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Eclipse CDT i inne narzędzia do C++</title><content type='html'>W zeszłe wakacje miałem ciekawy projekt i właśnie znalazłem zaległy post z tego czasu :)&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;Po 3 lata z Java i C# można zapomnieć co to jest segmentation fault albo destruktor. Jednak język to tylko narzędzie, jedno z wielu, a jeden telefon może sprawić by znów używać najlepszy i najgorszy z języków jakim jest C++. Na miejscu zbrodni zastałem Visual Studio 6. No tak, w sumie w zakresie C++ w Visual Studio względnie nie wiele się zmieniło przez te 10 lat, chociaż teraz jest to produkt darmowy również do zastosowań komercyjnych (&lt;a title="trochę okrojony" href="http://msdn.microsoft.com/en-us/library/hs24szh9.aspx" id="db5v"&gt;trochę okrojony&lt;/a&gt;).  W VC6 już pierwszego dnia, zaraz po ustawieniu środowiska i integracji z CVS (czyli instalacji WinCVS. Trudno o dobry plugin do jakiegokolwiek systemu kontroli wersji dla VS), przestała działać nawigacja po kodzie i autocompletion (lub jak kto woli IntelliSense). Wystarczy usunąć jeden plik i znów działa. Hmm, czekaj czekaj gdzie są zakładki w tym narzędziu? Nie znalazłem. Po trzech dniach uznałem, że cała gadanina o tym, że Java jest wolna nie może być dalsza od prawdy. Ctrl+S w VC6 oznacza, że mogę iść po wodę, po zmianie jednego pliku kompilacja oznacza, że mogę iść zrobić kawę. Problemu z Ctrl+S nie zniosłem, bo mam zwyczaj często ten skrót używać i pisać dalej, a nie czekać min. 30 sekund aż mi środowisko zacznie odpowiadać (nie VS6 nie ma czegoś takiego jak autobuild, nie ta liga, ot tak się po prostu działo). Pora poszukać alternatywy.  Dawno, dawno temu używałem &lt;a title="DJGPP" href="http://www.cppspace.qs.pl/djgpp.htm" id="oa7v"&gt;DJGPP&lt;/a&gt;, później prawdopodobnie największego przegranego wśród zwycięzców: bardzo dobrego &lt;a title="C++ Builder 6" href="http://en.wikipedia.org/wiki/C%2B%2B_Builder" id="jqsq"&gt;C++ Builder 6&lt;/a&gt;. Również &lt;a title="Dev-Cpp" href="http://www.bloodshed.net/devcpp.html" id="e:jd"&gt;Dev-Cpp&lt;/a&gt;(ciekawe, wersja 5 jest wersją beta od przynajmniej 4 lat) i całkiem udany &lt;a title="Code::Block" href="http://www.codeblocks.org/" id="bq:e"&gt;Code::Block&lt;/a&gt; który o ile dobrze pamiętam świetnie integrował się z darmowym kompilatorem od Borland. Oprogramowanie zmieniało się w razie potrzeby, odgórnej dyrektywy, dostępności licencji, ramu i wyposażenia biblioteki, stąd spora liczba środowisk których używałem (pomijając linuxowe jedno-projektowe przygody jak Anjuta). Przyszedł też czas na VS 2003 i skończyło się na VS 2005 - to było moje ostatnie środowisko, w którym używałem C++. Może przy okazji dam jeszcze szansę &lt;a title="VS 2008" href="http://www.microsoft.com/express/vc/" id="zq2v"&gt;VS 2008&lt;/a&gt;.   W omawianym zleceniu okazało się, że Notepad++ jest bardziej ergonomiczny niż VC6. Czasem lekki edytor jest wszystkim czego potrzeba. Przynajmniej póki tworze kod. Brakowało mi jednak możliwości efektywnego przeglądania tego co jest napisane (a jest tego dużo). No i czy naprawdę muszę odpalać kompilację, by dostać stos głupich błędów z powodu braku średnika ? Pora poszukać lepszego rozwiązania.&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;W praktyce z darmowych narzędzi polecam uwadze:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;ul id="viw60"&gt;&lt;li&gt;&lt;a id="wq7v" href="http://www.eclipse.org/cdt/" title="Eclipse CDT"&gt;Eclipse CDT&lt;/a&gt;  - systemy wbudowane, oprogramowanie dla Linux i podobnych, oraz jako "lekki" edytor plików cpp.&lt;br /&gt;&lt;/li&gt;&lt;li id="viw61"&gt;VS 2008 - oprogramowanie dla Windows, gry (choć wszędzie lepiej pasuje płatna wersja :) )&lt;/li&gt;&lt;li id="hytc"&gt;Code::Blocks - wszędzie ;) - lekkie choć kompletne IDE na różne platformy &lt;/li&gt;&lt;li id="hytc"&gt;MonoDevelop - Linux i/lub GTK, wygląda bardzo obiecująco - prosty i wystarczający, nie miałem okazji używać.&lt;/li&gt;&lt;/ul&gt; VC2008 odpadło z przyczyn środowiskowych. Zostaje Code::Blocks i Eclipse CDT. Już na wstępie Code::Blocks ma przewagę - obsługuje wszystkie sensowne kompilatory i projekty za równo VS jak i Dev-Cpp. Eclipse w praktyce wymaga gcc i gdb, na Windows działa to marnie i potrzeba Cygwin lub Mingw, a projekty portować trzeba ręcznie. Z drugiej strony Eclipse mogę wpiąć jako edytor w projekt nie zmieniając oryginalnego projektu, dalej mam dużo ciekawych. Niestety brak kompilacji i debug.   Ostatecznie korzystałem z Notpad++ do szkicu kodu (tydzień pisania samego pseudokodu dla pierwszej wersji algorytmu :) ), Eclipse CDT do edytowania / chodzenia po kodzie i Visual Studio do kompilacji i debug. Eclipse CDT ma własny parser i stara się równać poziomem do JDT. To nie jest proste ze względu na specyfikę C++. Mimo to dostaje się mnóstwo dobrych dodatków jak śledzenie "include" (które bierze pod uwagę stan zmiennych preprocesora), nawigacja po kodzie metodą Ctrl+Click, inteligentne podpowiedzi edytora, wyszukiwanie elementów, podstawowy refactoring, outline, Mylyn itp. &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;Linki:&lt;div&gt;&lt;a href="http://kwesoly.net/programowanie/cpp/eclipse-cdt/"&gt;http://kwesoly.net/programowanie/cpp/eclipse-cdt/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://wascana.sourceforge.net/"&gt;http://wascana.sourceforge.net/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-184563023920033831?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/184563023920033831/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=184563023920033831' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/184563023920033831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/184563023920033831'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2009/03/eclipse-cdt-i-inne-narzedzia-do-c.html' title='Eclipse CDT i inne narzędzia do C++'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-9046166004714375858</id><published>2008-10-10T00:49:00.001+02:00</published><updated>2008-10-10T00:49:57.164+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>W czym pisać "poważny artykuł" i jak to robić w grupie?</title><content type='html'>&lt;p&gt;Zanosi się na to, że praca magisterska będzie dla mnie projektem grupowym. Właśnie w dwuosobowym zespole przechodzimy pierwsze szlify, a to u mnie zawsze oznacza wybranie zabawek do skrzynki narzędziowej. &lt;/p&gt;  &lt;p&gt;Z raportami / artykułami pojawia się parę problem&amp;#243;w:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Zarządzanie bibliografią&lt;/li&gt;    &lt;li&gt;Zarządzanie odniesieniami do bibliografii, figur, tabel etc.&lt;/li&gt;    &lt;li&gt;Dbanie o wygląd całości&lt;/li&gt;    &lt;li&gt;Dbanie o zgodność wyglądu i struktury z narzuconymi wymaganiami&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Zajmowanie się poprawnością zar&amp;#243;wno merytoryczną jak i wizualną jest męczące, a wsp&amp;#243;łczesne procesory tekstu wcale nie poprawiają tutaj sytuacji. Mimo zaawansowanych opcji do pracy grupowej jak por&amp;#243;wnywanie wersji, komentarze i rozwiązania do tworzenia link&amp;#243;w, tabel, spis&amp;#243;w treści, bibliografii i obsługi stylu... zawodzą. Jeśli artykuł jest kr&amp;#243;tki i zmiany wprowadzane są we względnie dużych odstępach czasu, to najbardziej znane oprogramowanie może się sprawdzić, a r&amp;#243;żne wersje można przesyłać mailem i korzystać z opcji ich por&amp;#243;wnania i komentarzy. W taki spos&amp;#243;b pisałem ostatni &amp;quot;poważny&amp;quot; artykuł i poza problemem z trzymaniem się szablonu (kt&amp;#243;ry przychodził z własnymi makrami do formatowania) innych tym razem nie było.&lt;/p&gt;  &lt;p&gt;Jednak dalej nie wszystko mi pasowało, więc przy kolejnej okazji spr&amp;#243;bowałem czegoś innego. Informatyka twierdzi, że &amp;quot;Separation of Concerns&amp;quot; jest dobre, tak więc warto przetestować to i w tym wypadku.&lt;/p&gt;  &lt;p&gt;Ostatecznie pudełko składa się z:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;LaTeX + BibTex&lt;/li&gt;    &lt;li&gt;SVN + Trac&lt;/li&gt;    &lt;li&gt;Eclipse + Texlipse + ECF (Cola) + Subversive&lt;/li&gt;    &lt;li&gt;Lyx&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Wyb&amp;#243;r LaTeX-a pozwala zapomnieć o problemach zgodności z szablonem, właśnie dzięki oddzieleniu zawartości od opisu wyglądu. Wyglądu zwykle się tu nie opisuje ale znajduje odpowiednią klasę (na 95% jeśli gdzieś wymagają zgodności z szablonem od informatyka, to istnieje odpowiednia klasa LaTeX). Trzeba poświęcić odrobinę czasu by nauczyć się LaTeX-a, ale by prawidłowo używać wsp&amp;#243;łczesnego edytora tekstu trzeba go nie mniej. BibTex pozwala mi trzymać wszystkie referencje z &lt;strong&gt;każdej&lt;/strong&gt; pracy w jednym miejscu. Referencje są tworzone tylko do tych źr&amp;#243;deł,&amp;#160; kt&amp;#243;re rzeczywiście w aktualnej pracy używam. W każdej pracy są wyświetlane stosownie do wymaganego stylu. SVN pozwala na wygodną pracę grupową z porządną historią wersji, a LaTeX jako plik tekstowy idealnie się nadaje do wrzucenia na SVN. Trac z kolei pozwala na zarządzanie SVN, tworzenie planu i prowadzeniem wiki. Na naszym wiki pojawiły się definicje i opisy, kt&amp;#243;re nie trafiły do aktualnego dokumentu, zbieramy wszystko co może nam się przydać w przyszłości w jednym, bardzo wygodnym miejscu. Wyb&amp;#243;r Texlipse pozwala na integrację edytora do LaTeX-a z SVN, jednocześnie z dodatkiem ECF można niekt&amp;#243;re zmiany dyskutować na &amp;quot;żywo&amp;quot; (więcej [tutaj]). Czasem przeglądanie czystego TeX-a męczy, więc do przeglądu i poprawek używam Lyx, kt&amp;#243;ry na bieżąco edytuje przybliżony podgląd dokumentu jednocześnie nie pozwalając na nieprawidłowe formatowanie.&lt;/p&gt;  &lt;p&gt;W efekcie otrzymuje się profesjonalnie wyglądający i po prostu ładny dokument.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-9046166004714375858?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/9046166004714375858/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=9046166004714375858' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/9046166004714375858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/9046166004714375858'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/10/w-czym-pisa-artyku-i-jak-to-robi-w.html' title='W czym pisać &amp;quot;poważny artykuł&amp;quot; i jak to robić w grupie?'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-2470419791855322866</id><published>2008-09-26T14:36:00.007+02:00</published><updated>2008-09-26T14:52:46.085+02:00</updated><title type='text'>Aktualności</title><content type='html'>Całkiem sporo się stało w ciągu miesięcznej przerwy od bloga. Zakończyłem jeden projekt, zmieniłem tymczasowo miejsce mojego przebywania z Wrocławia na Szwecję, a Microsoft dołącza do OMG.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Ad. 1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Projekt uświadomił mi, że czasem istnieje potrzeba by używać C++ i Visual Studio 6. O ile obawiałem się jak będzie z powrotem do C++ po ostatnich miesiącach Java i .Net, o tyle problemem  nie był język, ale środowisko VS 6. Jeśli ktoś musi korzystać z Visual C++ to i tak (w pełni świadomy tego co mówię) polecam Eclipse CDT. Nie ma co liczyć również na nowe wersje VS, wygląda jakby rozwój wsparcia dla C++ (zwłaszcza klasycznego, nie zarządzanego) się zatrzymał. Eclipse okazał się znacznie lepszym edytorem, zwłaszcza przy okazji przeglądania kodu (np. przeglądanie #include,&lt;br /&gt;śledzenie referencji biorąc pod uwagę stan zmiennych preprocesora i mnóstwo innych drobiazgów). Mimo to w pracy używałem do kompilacji Visual Studio. Swoją drogą jeśli jest wystarczająco dużo RAM(minimum 512) to Eclipse jest odczuwalnie szybszy od VS6 (choć to jest bardzo dyskusyjne,  bo część działa szybciej, część wolniej i pewnie zależy co kogo irytuje),  ale przełączanie się na niego z innego programu, potrafi zająć trochę czasu.&lt;br /&gt;&lt;br /&gt;ps.&lt;br /&gt;Myślę, że normalna firma nie zaakceptuje Eclipse w projektach VS6 do póki nie pojawi się integracja z kompilatorem innym niż gcc i poprawi możliwość migracji projektów. Samo uruchomienie Eclipse CDT na Windows nie jest bezproblemowe. Polecam projekt &lt;a id="ttrr" href="http://wascana.sourceforge.net/" title="Wascana"&gt;Wascana&lt;/a&gt; – dystrybucja Eclipse razem z kompilatorem, która po prostu działa. Dodatkowo w Wascanie planowana jest integracja z kompilatorem Visual C++ (kompilacja, debug etc.), czyli większość tego, czego teraz brakuje.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Ad. 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Trafiłem chwilowo na studia do Szwecji. Prowadzący przedmiot Software Architecture stwierdził, że studia w Szwecji można przedstawić tak:&lt;br /&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Studia:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;                      Nauka&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;    &lt;/span&gt;&lt;img src="http://docs.google.com/File?id=dp45k7c_73gp542x2h_b" align="LEFT" hspace="13" /&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;p class="western" style="margin-left: 1.97in; margin-bottom: 0.14in"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Zabawa                                Sen&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span class="Apple-style-span"  style=" ;font-size:13px;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0.14in"&gt;&lt;span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Wybierz dwa.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Można też zrobić funkcjonalność - budżet - czas. Polscy studenci doszli do wniosku, że w Polsce,&lt;br /&gt;przynajmniej na PWr / IZ / IO można wybrać co najwyżej jedno.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Ad. 3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Microsoft i OMG? Dla mnie jest to bardzo istotna zmiana postawy. Podobno MS chce zacząć wspierać UML, a przede wszystkim zależy im na modelowaniu za pomocą DSL. Jeśli MS zdecydowałby się na wykorzystanie XMI i MOF to wtedy niewielkim nakładem pracy, wszystkie projekty powstałe w ramach Eclipse i inne związane z MDA będą mogły współpracować z Microsoft DSL Toolkit, który intensywnie się rozwija [&lt;a id="gq:g" href="http://startbigthinksmall.wordpress.com/2008/09/19/dsl-tools-software-factories-and-oslo-model-driven-the-microsoftnet-way/" title="DSL Tools, Software Factories and Oslo - Model-driven the Microsoft .NET way"&gt;DSL Tools, Software Factories and Oslo - Model-driven the Microsoft .NET way&lt;/a&gt;]. DSL Toolkit jest aktualnie jednym z najbardziej dostępnych narzędzi do tworzenia graficznych języków dziedzinowych. Nie ma praktycznie możliwości przekształcania między modelami (co zrozumiałe zwarzywszy na podejście)  i ma totalnie archaiczny język do generowania kodu T4 (myślałem (zresztą nie ja jedyny) by spróbować połączyć oAW i DSL Toolkit).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-2470419791855322866?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/2470419791855322866/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=2470419791855322866' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/2470419791855322866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/2470419791855322866'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/09/cakiem-sporo-si-stao-w-cigu-miesicznej.html' title='Aktualności'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-8857911946065288382</id><published>2008-08-16T14:13:00.008+02:00</published><updated>2008-10-13T17:35:24.551+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 6 - przykład z ANT, XML i plikami</title><content type='html'>Pewnego dnia czekało na mnie czterdzieści parę projektów do statycznej analizy kodu. Pojawił się problem, ponieważ projekty pochodziły z SVN, wszystkie nazywały się tak samo i miały nie wygodną strukturę folderów. By policzyć metryki musiałem wszystkie projekty zaimportować do Eclipse. Groovy był wtedy na mojej liście narzędzi, które chce dodać do swojego pudełka. Poniższe skrypty powstały w około 30 - 40 minut wraz z nauką Groovy od zera i szukaniem odpowiednich poleceń ANT. Były pierwsze linijki kodu jaki napisałem w Groovy i wklejam je w wersji oryginalnej. Warto zauważyć, że Groovy jest produktywny już od momentu zaczęcia nauki. Skrypty pisane były w GroovyConsole.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Skrypt I&lt;/span&gt;&lt;br /&gt;Kopiuje pliki \pXX\project\* bezpośrednio do \pXX\*&lt;br /&gt;&lt;pre name="code" class="scala"&gt;def f = new File("E:\\Pomiary")&lt;br /&gt;AntBuilder ant = new AntBuilder()&lt;br /&gt;&lt;br /&gt;f.eachDir{ dir_pXX -&gt;&lt;br /&gt;print(dir_pXX)&lt;br /&gt;&lt;br /&gt;dir.eachDir{d -&gt; if(d.name == "project"){&lt;br /&gt;  ant.move(todir: dir_pXX){&lt;br /&gt;     fileset(dir: d, defaultexcludes: "no") {&lt;br /&gt;        include(name: '**')&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;AntBuilder to klasa pozwalająca na używanie zadań Ant bezpośrednio w kodzie Groovy. Korzysta z kilku przedstawionych wcześniej &lt;a href="http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-4-mapy-12.html"&gt;map&lt;/a&gt; i &lt;a href="http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-2-zapomnij-o.html"&gt;domknięć&lt;/a&gt;. W wyrażeniu&lt;br /&gt;&lt;pre name="code" class="scala"&gt;ant.move(todir: dir_pXX){&lt;br /&gt;fileset(dir: d, defaultexcludes: "no"){&lt;br /&gt;  include(name: '**')&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;Wszystkie nawiazy klamrowe to domknięcia, a wszystkie parametry funkcji:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;dir: d, defaultexcludes: "no"&lt;br /&gt;&lt;/pre&gt;to definicja mapy. Takie budowanie struktur jest powszechne w Groovy, nazywane Builder i dostępne przykładowo dla Swing i wielu innych struktur drzewiastych.&lt;br /&gt;&lt;a href="http://docs.codehaus.org/display/GROOVY/Recipes+For+File"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Skrypt II&lt;/span&gt;&lt;br /&gt;W każdym ze skopiowanych folderów znajduje się projekt Eclipse o nazwie "project". Nie można importować kilku projektów o tej samej nazwie do Eclipse więc potrzeba te nazwy zmienić. Nazwa projektu jest zdefiniowana w pliku xml, przy odrobinie szczęścia wystarczyłoby podmienić za pomocą wyrażenia regularnego wystąpienia "project". No ale wtedy nie sprawdzimy jak Groovy radzi sobie z XML.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;def f = new File("E:\\Pomiary")&lt;br /&gt;f.eachDir{ dir -&gt;&lt;br /&gt;dir.eachFile{file -&gt;&lt;br /&gt;  if(file.name == ".project"){&lt;br /&gt;     def projectDescription = new XmlParser().parseText(file.getText())&lt;br /&gt;     projectDescription.name[0].value = dir.name&lt;br /&gt;     def writer = new FileWriter(file)&lt;br /&gt;     new XmlNodePrinter(new PrintWriter(writer)).print(projectDescription)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Zauważyliście &lt;span style="font-family:courier new;"&gt;File.getText()&lt;/span&gt;? Małe a cieszy. Najciekawszą linijką jest linijka&lt;br /&gt;&lt;pre name="code" class="scala"&gt;projectDescription.name[0].&lt;wbr&gt;value = dir.name&lt;/pre&gt;Groovy pozwala na korzystanie podstawowych wyrażeń &lt;a href="http://www.w3schools.com/XPath/xpath_syntax.asp"&gt;XPath &lt;/a&gt;bezpośrednio w języku. Po tak wybranych elementach można się iterować z pomocą &lt;span style="font-family:courier new;"&gt;each&lt;/span&gt;, można pobierać lub przypisywać im wartość. Odwołanie do atrybutów też jest możliwe np. &lt;span style="font-family:courier new;"&gt;node.'@atrybut'&lt;/span&gt;. Nie wszystko da się zapisać tak samo jak w XPath, ale produktywność jest wspaniała. Może o XML napisze więcej w innym poscie.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Skrypt III&lt;/span&gt;&lt;br /&gt;Plug-in liczący metryki zapisywał wyniki w folderach analizowanych projektów, więc jeszcze mały skrypt co zbierał wyniki w jedno miejsce.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;def f = new File("E:\\Pomiary")&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;&lt;br /&gt;f.eachDir{ dir -&gt;&lt;br /&gt;    dir.eachFile{file -&gt;&lt;br /&gt;           if(file.name == "results.xls"){&lt;br /&gt;                  ant.copy(file: file,toFile: new File("E:\\Pomiary\\Wyniki\\${dir.name}.xls"))&lt;br /&gt;           }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Linki&lt;/span&gt;&lt;br /&gt;Podstawy &lt;a href="http://groovy.codehaus.org/Using+Ant+from+Groovy"&gt;Groovy i ANT&lt;/a&gt;&lt;br /&gt;Więcej informacji &lt;a href="http://ant.apache.org/manual/CoreTypes/fileset.html"&gt;Ant Fileset&lt;/a&gt;, &lt;a href="http://ant.apache.org/manual/CoreTasks/move.html"&gt;Ant Move&lt;/a&gt;, &lt;a href="http://groovy.codehaus.org/JN2015-Files"&gt;klasa File&lt;/a&gt;&lt;br /&gt;Inne przykłady pracy z plikami &lt;a href="http://docs.codehaus.org/display/GROOVY/Recipes+For+File"&gt;Groovy i Pliki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ps. To były pierwsze kroki z Groovy i całkiem sporo elementów w tych prostych skryptach da się zrobić lepiej. Najbardziej mnie drażni w tym starym kodzie korzystanie "\\" i nie korzystanie z choćby &lt;span style="font-family:courier new;"&gt;File.eachFileMatch&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-8857911946065288382?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/8857911946065288382/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=8857911946065288382' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/8857911946065288382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/8857911946065288382'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/08/groovy-w-praktyce-part-6-przykad-z-ant.html' title='Groovy w praktyce - part 6 - przykład z ANT, XML i plikami'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7247764654081775916</id><published>2008-07-31T19:01:00.006+02:00</published><updated>2008-08-16T15:36:07.380+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 5 - mapy 2/2</title><content type='html'>Pora wrócić do Groovy po drobnej przerwie.&lt;br /&gt;&lt;br /&gt;Pewną szczególną cechą Groovy jest podejście do interfejsów w połączeniu z mapami i domknięciami. Tym razem włączam groovyConsole i...&lt;br /&gt;&lt;pre name="code" class="scala"&gt;interface Kaczka{&lt;br /&gt;void kwa()&lt;br /&gt;void lataj()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def PrawieJezioroLabedzie(Kaczka k){&lt;br /&gt;6.times{k.kwa()}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def mapa = [ kwa:{println 'kwa'}, lataj: {println 'ja latam!'} ]&lt;br /&gt;def kaczka = mapa as Kaczka&lt;br /&gt;&lt;br /&gt;if(kaczka instanceof Kaczka){&lt;br /&gt;PrawieJezioroLabedzie(kaczka)&lt;br /&gt;kaczka.lataj()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Wynik:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;ja latam!&lt;br /&gt;&lt;/pre&gt;To przecież jakaś herezja ! Dynamicznie tworzę instancję interfejsu za pomocą zawartości mapy. Jak to możliwe? W Javie od wersji 1.3 można dynamicznie tworzyć nowe implementacje klas i interfejsów! Jest to możliwe za pomocą &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html"&gt;Dynamic Proxy&lt;/a&gt;, łatwo można sprawdzić, że Groovy wykorzystuje ten mechanizm.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;println java.lang.reflect.Proxy.isProxyClass(kaczka.class)&lt;br /&gt;&lt;/pre&gt;Wynik:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wstrzykiwanie zależności, aspekty, zarządzane ziarna, binding, rmi ... wszystko to wykorzystuje dynamic proxy. Ma to swoje minusy. Proxy, jak przystało na twór dynamiczny, będzie wolniejszy od normalnej klasy. Jest to cena warta zapłacenia, jeśli chcesz stworzyć jakikolwiek zarządzany komponent to trudno nie wykorzystać proxy. .Net ma podobny twór o mniejszych możliwościach (bo m.in. w C# metody są domyślnie nie wirtualne, takiego wywołania nie można dynamicznie przechwycić, więc tylko niektóre metody proxy może implementować).&lt;br /&gt;&lt;br /&gt;Można też rzutować pojedyncze domknięcie na interfejs&lt;br /&gt;&lt;pre name="code" class="scala"&gt;PrawieJezioroLabedzie({println "ćwir"} as Kaczka)&lt;br /&gt;&lt;/pre&gt;Wynik:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;ćwir&lt;br /&gt;ćwir&lt;br /&gt;ćwir&lt;br /&gt;ćwir&lt;br /&gt;ćwir&lt;br /&gt;ćwir&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wtedy wszystkim funkcją interfejsu zostanie przypisana jedna akcja. Co ciekawe niektóre z propozycji &lt;a href="http://www.javac.info/closures-v05.html"&gt;domknięć&lt;/a&gt; dla Java pozwalają na niejawne zamienianie domknięć na interfejsy. Jest to niebywale wygodne, gdy definiujemy zdarzenia np. w GUI.&lt;br /&gt;&lt;br /&gt;Groovy sprawdza w trakcie wykonania typy obiektów dlatego poniższy kod jest nie poprawny.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;PrawieJezioroLabedzie(mapa)&lt;br /&gt;// powoduje&lt;br /&gt;Exception thrown: groovy.lang.MissingMethodException: No signature of method: Script12.PrawieJezioroLabedzie() is applicable for argument types: (java.util.LinkedHashMap)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Jeśli jednak usunę informację o oczekiwanym typie z parametru funkcji, to funkcja nie będzie widzieć różnicy między klasą, a mapą i w obu przypadkach wykona się poprawnie.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;def PrawieJezioroLabedzie(k){&lt;br /&gt;6.times{k.kwa()}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;PrawieJezioroLabedzie(mapa)&lt;br /&gt;&lt;/pre&gt;Wynik&lt;br /&gt;&lt;pre name="code" class="scala"&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;kwa&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Więcej w &lt;a href="http://groovy.codehaus.org/Groovy+way+to+implement+interfaces"&gt;implementacja interfejsów w Groovy&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7247764654081775916?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7247764654081775916/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7247764654081775916' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7247764654081775916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7247764654081775916'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-5-mapy-22.html' title='Groovy w praktyce - part 5 - mapy 2/2'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-4892883786403332258</id><published>2008-07-30T22:34:00.007+02:00</published><updated>2008-07-31T00:28:30.734+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 4 - mapy 1/2</title><content type='html'>Mapa w Groovy jest reprezentowana przez zwykłą klasę Javy,  używać ją można jak zwykłą mapę, klasę asocjacyjną, a nawet obiekt.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; a = [:]&lt;br /&gt;===&gt; {}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.getClass()&lt;br /&gt;===&gt; class java.util.LinkedHashMap&lt;br /&gt;&lt;br /&gt;// iteracje po mapie mozna wykonac na kilka sposobow&lt;br /&gt;groovy&gt; a = [a:'aa',b:'bb']&lt;br /&gt;===&gt; {a=aa, b=bb}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.each{println it}&lt;br /&gt;a=aa&lt;br /&gt;b=bb&lt;br /&gt;===&gt; {a=aa, b=bb}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.each{println it.key}&lt;br /&gt;a&lt;br /&gt;b&lt;br /&gt;===&gt; {a=aa, b=bb}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.each{println it.value}&lt;br /&gt;aa&lt;br /&gt;bb&lt;br /&gt;===&gt; {a=aa, b=bb}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.each{ key,value -&gt; println key + ' - ' + value }&lt;br /&gt;a - aa&lt;br /&gt;b - bb&lt;br /&gt;===&gt; {a=aa, b=bb}&lt;br /&gt;&lt;br /&gt;// ustawianie i odczytywanie elementów jest proste,&lt;br /&gt;groovy&gt; a.a&lt;br /&gt;===&gt; aa&lt;br /&gt;groovy&gt; a.b&lt;br /&gt;===&gt; bb&lt;br /&gt;groovy&gt; a.c&lt;br /&gt;===&gt; null&lt;br /&gt;// ale z powodu takiej konwencji a.class == null, dlatego wcześniej użyłem getClass()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// na mapie można bezpośrednio tworzyć nowy element  w analogiczny sposób&lt;br /&gt;groovy&gt; a.c = 'cc'&lt;br /&gt;===&gt; cc&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; {a=aa, b=bb, c=cc}&lt;br /&gt;groovy&gt; a['d'] = 123&lt;br /&gt;===&gt; 123&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; {a=aa, b=bb, c=cc, d=123}&lt;br /&gt;&lt;br /&gt;groovy&gt; a.keySet()&lt;br /&gt;===&gt; [a, b, c, d]&lt;br /&gt;groovy&gt; a.values()&lt;br /&gt;===&gt; [aa, bb, cc, 123]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Klucz w mapie domyslnie jest traktowany jako string, chyba ze jest liczbą, wartością logiczną lub null.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; b = [1:1,a:2]&lt;br /&gt;===&gt; {1=1, a=2}&lt;br /&gt;groovy&gt; b[1]&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; b['a']&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; b.'1'&lt;br /&gt;===&gt; null&lt;br /&gt;groovy&gt; b[a]&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Jeśli chcemy jako klucz użyć coś innego niż liczbę czy string to możemy użyć notacji tabeli asocjacyjnej mapa[obiekt], albo nawiasów():&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; x = [1,2]&lt;br /&gt;===&gt; [1, 2]&lt;br /&gt;groovy&gt; y = [ (x):'abc' ] //dzieki nawiasom w tym przypadku kluczem będzie lista&lt;br /&gt;===&gt; {[1, 2]=abc}&lt;br /&gt;groovy&gt; y.keySet()*.getClass()&lt;br /&gt;===&gt; [class java.util.ArrayList]&lt;br /&gt;groovy&gt; y.each{println it.key[1]}&lt;br /&gt;2&lt;br /&gt;===&gt; {[1, 2]=abc}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Jeśli mapa jest parametrem funkcji to większości przypadków można porzucić nawiasy []&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; f = {mapa -&gt; mapa.values().each{ println it }}&lt;br /&gt;===&gt; groovysh_evaluate$_run_closure1@1e46a68&lt;br /&gt;groovy&gt; f([a:1])&lt;br /&gt;1&lt;br /&gt;===&gt; [1]&lt;br /&gt;groovy&gt; f([a:1,b:2])&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;===&gt; [1, 2]&lt;br /&gt;groovy&gt; f(a:1,b:2)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;===&gt; [1, 2]&lt;/pre&gt;nawet jeśli mapa nie jest jedynym parametrem&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; g = {mapa, foo -&gt; println mapa}&lt;br /&gt;===&gt; groovysh_evaluate$_run_closure1@d480ea&lt;br /&gt;groovy&gt; g(a:1,2)&lt;br /&gt;["a":1]&lt;br /&gt;===&gt; null&lt;br /&gt;groovy&gt; g(a:1,b:2,2)&lt;br /&gt;["a":1, "b":2]&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Języki dynamicznie z domknięciami mają ciekawą cechę, mapa odpowiada w pewnym stopniu obiektowi, np. w ActionScript 2 nie ma osobnej kolekcji "Mapa" - korzysta się z Obiektów i dynamicznie tworzy nowe pola wygląda to tak jak kod w 3 linijce.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; a = [:]&lt;br /&gt;===&gt; {}&lt;br /&gt;groovy&gt; a.pole = 1&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; a.funkcja = { x -&gt; x * a.pole } // ! trzeba zapisać skąd pochodzi "pole", m.in. tym się różni od normalnego obiektu&lt;br /&gt;===&gt; groovysh_evaluate$_run_closure1@20f237&lt;br /&gt;groovy&gt; a.funkcja(2)&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; a.pole = 2&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; a.funkcja(2)&lt;br /&gt;===&gt; 4&lt;br /&gt;groovy&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Teraz, chwila przerwy, by każdy czytelnik mógł się zastanowić jak proste jest tworzenie mocków w Groovy za pomocą takich opcji.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Istnieje jeszcze jedna specjalna klasa - Expando - która w pewien, jak na razie magiczny, sposób pozwala na bardziej naturalne tworzenie dynamicznych obiektów.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy&gt; e = new Expando()&lt;br /&gt;===&gt; {}&lt;br /&gt;groovy&gt; e.pole = 1&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; e.f = { x -&gt; x * pole } // ! nie trzeba specyfikować z jakiego obiektu pochodzi pole, czyli to czego oczekujemy&lt;br /&gt;===&gt; groovysh_evaluate$_run_closure1@174aa60&lt;br /&gt;groovy&gt; e.f(2)&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; e.pole = 2&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; e.f(2)&lt;br /&gt;===&gt; 4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Przetestuj&lt;/b&gt; poniższy kod, zapamiętaj co się dzieje [ zakładam, że wiesz dlaczego ;) ]&lt;br /&gt;&lt;pre name="code" class="scala"&gt;a = [a:1]&lt;br /&gt;e = new Expando()&lt;br /&gt;e.a = 1&lt;br /&gt;e.f = { x -&gt; x * a }&lt;br /&gt;e.f(2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/JN1035-Maps"&gt;Więcej o mapach&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-4892883786403332258?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/4892883786403332258/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=4892883786403332258' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4892883786403332258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4892883786403332258'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-4-mapy-12.html' title='Groovy w praktyce - part 4 - mapy 1/2'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-2580298022600837951</id><published>2008-07-29T19:26:00.007+02:00</published><updated>2008-07-29T20:36:37.600+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 3 - listy i kilka operatorów</title><content type='html'>Najpierw parę operatorów.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;*. - pozwala na zgrupowanie wyników pewnej operacji a*.b() odpowiada a.collect{ it.b()},  domyślny sposób nawigacji w OCL i XPath&lt;br /&gt;&lt;/li&gt;&lt;li&gt;?. - bezpieczna nawigacja - jeśli a= null to a?.b też wynosi null&lt;/li&gt;&lt;li&gt;?: - doskonały dla wartości domyślny - zwraca wartość po prawej jeśli po lewej jest null, pusty string, false lub 0&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre name="code" class="scala"&gt;//&lt;br /&gt;// Operator .*&lt;br /&gt;//&lt;br /&gt;groovy&gt; "abc".toList()&lt;br /&gt;===&gt; [a, b, c]&lt;br /&gt;groovy&gt; a = "abc".toList()&lt;br /&gt;===&gt; [a, b, c]&lt;br /&gt;groovy&gt; a*.toUpperCase()&lt;br /&gt;===&gt; [A, B, C]&lt;br /&gt;groovy&gt; a.collect{ it.toUpperCase()}&lt;br /&gt;===&gt; [A, B, C]&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// Operator ?.&lt;br /&gt;//&lt;br /&gt;groovy&gt; class A{ def a }         &lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;groovy&gt; a = new A()&lt;br /&gt;===&gt; A@c1a0eb&lt;br /&gt;groovy&gt; a.a = new A()&lt;br /&gt;===&gt; A@ed9f47&lt;br /&gt;groovy&gt; a.a.a = new A()&lt;br /&gt;===&gt; A@1762027&lt;br /&gt;&lt;br /&gt;groovy&gt; a.a?.a&lt;br /&gt;===&gt; A@1762027&lt;br /&gt;&lt;br /&gt;groovy&gt; a.a = null&lt;br /&gt;===&gt; null&lt;br /&gt;groovy&gt; a.a?.a&lt;br /&gt;===&gt; null&lt;br /&gt;groovy&gt; a.a.a&lt;br /&gt;ERROR java.lang.NullPointerException: null&lt;br /&gt;     at groovysh_evaluate.run (groovysh_evaluate:1)&lt;br /&gt;     ...&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// Operator ?:&lt;br /&gt;//&lt;br /&gt;groovy&gt; null?:2&lt;br /&gt;===&gt; 2&lt;br /&gt;&lt;br /&gt;groovy&gt; 1?:2&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; 0?:2&lt;br /&gt;===&gt; 2&lt;br /&gt;&lt;br /&gt;groovy&gt; true?:2&lt;br /&gt;===&gt; true&lt;br /&gt;groovy&gt; false?:2&lt;br /&gt;===&gt; 2&lt;br /&gt;&lt;br /&gt;groovy&gt; ''?:2&lt;br /&gt;===&gt; 2&lt;br /&gt;groovy&gt; 'x'?:2&lt;br /&gt;===&gt; x&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A teraz listy, niech kod mówi sam za siebie.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;Groovy Shell (, JVM: 10.0-b22)&lt;br /&gt;Type 'help' or '\h' for help.&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;groovy&gt; a = [1,2,3]&lt;br /&gt;===&gt; [1, 2, 3]&lt;br /&gt;groovy&gt; a.class&lt;br /&gt;===&gt; class java.util.ArrayList&lt;br /&gt;&lt;br /&gt;groovy&gt; a + 4&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3]&lt;br /&gt;&lt;br /&gt;groovy&gt; a &amp;lt;&amp;lt; 4&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;&lt;br /&gt;groovy&gt; a - 3&lt;br /&gt;===&gt; [1, 2, 4]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;&lt;br /&gt;groovy&gt; a -= 3&lt;br /&gt;===&gt; [1, 2, 4]&lt;br /&gt;groovy&gt; a += 3&lt;br /&gt;===&gt; [1, 2, 4, 3]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 4, 3]&lt;br /&gt;&lt;br /&gt;groovy&gt; a.sort()&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;&lt;br /&gt;groovy&gt; a + [5,6,7]&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;groovy&gt; a &amp;lt;&amp;lt; [5,6,7]&lt;br /&gt;===&gt; [1, 2, 3, 4, [5, 6, 7]]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;groovy&gt; a.pop()&lt;br /&gt;===&gt; [5, 6, 7]&lt;br /&gt;&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4]&lt;br /&gt;&lt;br /&gt;groovy&gt; a += [5,6,7]&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7]&lt;br /&gt;&lt;br /&gt;groovy&gt; a += (8..10)&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;&lt;br /&gt;groovy&gt; a[0]&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; a.get(0)&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; a.getAt(0)&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; a.getAt([0,-3..-1])&lt;br /&gt;===&gt; [1, 8, 9, 10]&lt;br /&gt;groovy&gt; a[-1]  &lt;br /&gt;===&gt; 10&lt;br /&gt;groovy&gt; a[4..-1]&lt;br /&gt;===&gt; [5, 6, 7, 8, 9, 10]&lt;br /&gt;groovy&gt; a == [*1..10]&lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;groovy&gt; a.each{println it}&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;&lt;br /&gt;groovy&gt;a.reverseEach{ println it}&lt;br /&gt;10&lt;br /&gt;9&lt;br /&gt;8&lt;br /&gt;7&lt;br /&gt;6&lt;br /&gt;5&lt;br /&gt;4&lt;br /&gt;3&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;===&gt; [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]&lt;br /&gt;groovy&gt; a.reverse().eachWithIndex{it,i -&gt; println "$i: $it"}&lt;br /&gt;0: 10&lt;br /&gt;1: 9&lt;br /&gt;2: 8&lt;br /&gt;3: 7&lt;br /&gt;4: 6&lt;br /&gt;5: 5&lt;br /&gt;6: 4&lt;br /&gt;7: 3&lt;br /&gt;8: 2&lt;br /&gt;9: 1&lt;br /&gt;===&gt; [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;&lt;br /&gt;groovy&gt; a.find{it &gt; 3}                                   &lt;br /&gt;===&gt; 4&lt;br /&gt;groovy&gt; a.findAll{it &gt; 3}&lt;br /&gt;===&gt; [4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;&lt;br /&gt;groovy&gt; a.every{it &gt; 3}&lt;br /&gt;===&gt; false&lt;br /&gt;groovy&gt; a.any{it &gt; 3}&lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;groovy&gt; a.max()&lt;br /&gt;===&gt; 10&lt;br /&gt;groovy&gt; a.min()&lt;br /&gt;===&gt; 1&lt;br /&gt;groovy&gt; a.sum()&lt;br /&gt;===&gt; 55&lt;br /&gt;&lt;br /&gt;groovy&gt; a.join()&lt;br /&gt;===&gt; 12345678910&lt;br /&gt;groovy&gt; a.join('-')&lt;br /&gt;===&gt; 1-2-3-4-5-6-7-8-9-10&lt;br /&gt;&lt;br /&gt;groovy&gt; a.intersect([8,9,10,11,12,13])&lt;br /&gt;===&gt; [8, 9, 10]&lt;br /&gt;groovy&gt; a.contains(1)              &lt;br /&gt;===&gt; true&lt;br /&gt;groovy&gt; a.containsAll([1,3,5])&lt;br /&gt;===&gt; true&lt;br /&gt;groovy&gt; a.disjoint([10,11])&lt;br /&gt;===&gt; false&lt;br /&gt;groovy&gt; a.disjoint([11,12])&lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;groovy&gt; a.multiply(2)   &lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;groovy&gt; a&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;groovy&gt; a * 2&lt;br /&gt;===&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]&lt;br /&gt;&lt;br /&gt;groovy&gt; a = "abc".toList()&lt;br /&gt;===&gt; [a, b, c]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Więcej: &lt;a href="http://groovy.codehaus.org/JN1015-Collections"&gt;Groovy - Kolekcje&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-2580298022600837951?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/2580298022600837951/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=2580298022600837951' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/2580298022600837951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/2580298022600837951'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-3-listy-i-kilka.html' title='Groovy w praktyce - part 3 - listy i kilka operatorów'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-4232916522708230959</id><published>2008-07-27T18:25:00.003+02:00</published><updated>2008-07-27T18:57:25.357+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 2 - "zapomnij o pętlach" czyli elementy stylu funkcyjnego</title><content type='html'>Dziś opowieść o funkcjach. Przyjmuje na razie pewne uproszczenie, bo tak naprawdę to nie funkcje ale domknięcia (&lt;a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29"&gt;closure&lt;/a&gt;) używam. Jednak wiedza czym domknięcia różnią się od funkcji nie jest na razie potrzebna i można.&lt;br /&gt;&lt;br /&gt;Plan jest prosty&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Jak używa się pętli w Groovy?&lt;/li&gt;&lt;li&gt;Jak to jest możliwe, że to da się tak zrobić?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt; Odpalam &lt;span style="font-weight: bold;"&gt;groovysh&lt;/span&gt;. Linijki zaczynające się od &lt;span style="font-weight: bold;"&gt;groovy&gt;&lt;/span&gt; to kod wpisany do interpretera. Tekst zaraz za taką linijką, a przed &lt;span style="font-weight: bold;"&gt;===&gt; &lt;/span&gt;to wyniki println, wartość po &lt;span style="font-weight: bold;"&gt;===&gt;&lt;/span&gt; to wartość wyrażenia.&lt;br /&gt;&lt;br /&gt;Pewną archaiczną konstrukcją języka odziedziczoną po Javie są pętle ;)&lt;br /&gt;&lt;pre name="code" class="java"&gt;int i = -1;&lt;br /&gt;while(i++ &amp;lt; 3){&lt;br /&gt; System.out.println(i);&lt;br /&gt;}&lt;br /&gt;// lub&lt;br /&gt;for(int i = 0; i &amp;lt; 4; i++){&lt;br /&gt; System.out.println(i);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Groovy rzeczywiście akceptuje tak napisany kod.&lt;br /&gt;&lt;pre name="code" class="java"&gt;groovy&gt; for(int i = 0; i &amp;lt; 4; i++){ System.out.println(i); }&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Ja jednak preferuje styl funkcyjny.&lt;br /&gt;&lt;pre name="code" class="java"&gt;groovy&gt; 4.times{ it -&gt; println(it) }                      &lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;br /&gt;// A najbardziej lubie&lt;br /&gt;&lt;br /&gt;groovy&gt; (0..3).each{ println it }&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;===&gt; null&lt;/pre&gt;&lt;br /&gt;Mając więc do wyboru&lt;br /&gt;&lt;pre name="code" class="java"&gt;for(int i = 0; i &amp;lt; 4; i++){&lt;br /&gt; System.out.println(i);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;lub&lt;br /&gt;&lt;pre name="code" class="java"&gt;(0..3).each{ println it }&lt;/pre&gt;&lt;br /&gt;Co wybierzecie? Gdzie łatwiej stwierdzić ile razy coś się wykona, albo co właściwie się stanie?&lt;br /&gt;Nie przekonani? To może inny przykład&lt;br /&gt;&lt;pre name="code" class="java"&gt;String s = "abcde";&lt;br /&gt;for(int i = 0; i &amp;lt; s.length(); i++){&lt;br /&gt; System.out.println(i);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//względem&lt;br /&gt;&lt;br /&gt;"abcde".each{ znak -&gt; println znak }&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;No ale jak to jest właściwie możliwe ?&lt;/span&gt;&lt;br /&gt;Wszystkie kolekcje oraz String i zakresy w Groovy mają przydatne funkcje jak each, find, collect, every, any itd. o których więcej w następnych częściach. Na razie wystarczy  wiedzieć, że funkcje te &lt;span style="font-weight: bold;"&gt;pobierają jako parametr zmienną będącą funkcją&lt;/span&gt;. Funkcja ta pobiera jako parametr jeden obiekt z kolekcji.&lt;br /&gt;&lt;br /&gt;No dobrze, ale żeby przesłać funkcję do innej funkcji najpierw trzeba ją zdefiniować.&lt;br /&gt;&lt;br /&gt;W Java można tworzyć funkcje jedynie bezpośrednio w klasach, Groovy tak też potrafi.&lt;br /&gt;&lt;pre name="code" class="java"&gt;// Java&lt;br /&gt;class A{&lt;br /&gt; public void f(Object x){&lt;br /&gt;     System.out.println(x);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Groovy&lt;br /&gt;groovy&gt; class A{ public void f(Object x){ System.out.println(x);} }&lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;// W Groovy można też pominąć wszystkie typy, pozbyć się średnika i skrócić System.out... do samego println&lt;br /&gt;class B{&lt;br /&gt;  public f(x){&lt;br /&gt;      println(x)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//uruchamiam funkcję&lt;br /&gt;groovy&gt; a = new A()&lt;br /&gt;===&gt; A@1de498&lt;br /&gt;groovy&gt; a.f(1)&lt;br /&gt;1&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;W Groovy można definiować funkcję praktycznie w dowolnym miejscu. Możemy to zrobić np. za pomocą &lt;span style="font-weight: bold;"&gt;def&lt;/span&gt;.&lt;br /&gt;&lt;pre name="code" class="java"&gt;groovy&gt; def f(x){ println(x) }&lt;br /&gt;===&gt; true&lt;br /&gt;groovy&gt; f(1)&lt;br /&gt;1&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;br /&gt;// tak zdefiniowaną funkcje mogę już wysłać do innej funkcji np.:&lt;br /&gt;&lt;br /&gt;groovy&gt; (0..3).each(f)      &lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;===&gt; 0..3&lt;/pre&gt;&lt;br /&gt;W językach funkcyjnych często tworzy się funkcje anonimowe, które są przypisywane zmiennym lub parametrom innych funkcji. Przykładowo możemy przypisać zmiennej g funkcję pobierającą Object i wypisującą go na ekran jako:&lt;br /&gt;&lt;pre name="code" class="java"&gt;g = { Object it -&gt; println(it); } // ten zapis możemy uprościć pozbywając się informacji o typie i średnika&lt;br /&gt;g = { it -&gt; println(it) } // nawiasy też nie są potrzebne ponieważ f(x) == f x - podobnie jak w Ocaml&lt;br /&gt;g = { it -&gt; println it }&lt;br /&gt;&lt;br /&gt;// ostatecznie mamy:&lt;br /&gt;groovy&gt; g = { it -&gt; println it }&lt;br /&gt;===&gt; groovysh_evaluate$_run_closure1@10e434d&lt;br /&gt;groovy&gt; g(1)&lt;br /&gt;1&lt;br /&gt;===&gt; null&lt;br /&gt;&lt;br /&gt;// tak stworzoną funkcję możemy ponownie wysłać do innej funkcji:&lt;br /&gt;groovy&gt; (0..3).each(g)     &lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;===&gt; 0..3&lt;br /&gt;&lt;br /&gt;(0..3).each(g) // możemy ponownie pozbyć się nawiasów&lt;br /&gt;(0..3).each g  // właściwie nie ma powodu by definiować osobną zmienną, możemy funkcję zdefiniować natychmiast&lt;br /&gt;(0..3).each { i -&gt; println i} // tutaj nazwaliśmy parametr i,&lt;br /&gt;// co ciekawe parametr o nazwie it jest parametrem domyślnym i nie trzeba go w ogóle specyfikować&lt;br /&gt;// więc można napisać:&lt;br /&gt;(0..3).each { println it }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ostatnia linijka kodu definiuje anonimową funkcję pobierająca jeden obiekt pod nazwą it i każe wykonać tą funkcję dla każdego obiektu z zakresu od 0 do 3 włącznie.&lt;br /&gt;I tym sposobem zatoczyłem koło.&lt;br /&gt;&lt;br /&gt;Na taki styl pozwalają języki, które traktują funkcje jak zwykłe obiekty (&lt;a href="http://en.wikipedia.org/wiki/First-class_function"&gt;First-class function&lt;/a&gt;), więc np. JavaScript, Ruby, Python, ActionScript, Scala. Jeśli pozwalają to na pewno z niego korzystają. Jeśli komuś się taki styl nie podoba, to muszę przyznać, że ma pecha.  Nawet następny standard C++ (&lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;C++0x&lt;/a&gt;) będzie najpewniej mieć domknięcia, C# już je ma, a Java ma 3 propozycje domknięć i prawdopodobnie w Java 1.7 domknięcia już będą. Pewnie nie tak ładnie syntaktycznie jak w Groovy, ale będą.&lt;br /&gt;Innymi słowy w 2010 wszystkie główne języki programowania będą obsługiwać domknięcia. I to pełne domknięcia, nie tylko funkcje jako obiekty (a co to tak naprawdę  oznacza, to może innym razem).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-4232916522708230959?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/4232916522708230959/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=4232916522708230959' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4232916522708230959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4232916522708230959'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-2-zapomnij-o.html' title='Groovy w praktyce - part 2 - &quot;zapomnij o pętlach&quot; czyli elementy stylu funkcyjnego'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-1508661878925372438</id><published>2008-07-25T07:00:00.000+02:00</published><updated>2008-07-25T23:03:18.506+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy w praktyce - part 1 - instalacja i  String</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Wymagania wstępne&lt;br /&gt;&lt;/span&gt;Java&lt;span style="font-weight: bold;"&gt;, &lt;/span&gt;najlepiej &gt;=1.5. Na 1.4 będzie działać, ale bez niektórych opcji.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Instalacja - Linux&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ubuntu:  &lt;span style="font-weight: bold;"&gt;sudo apt-get install groovy&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://download.opensuse.org/repositories/home:/eggeral/openSUSE_11.0/noarch/groovy-1.5.6-10.1.noarch.rpm"&gt;OpenSuse &gt;=10.2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Ewentualnie wszelkie pliki można dostać tu &lt;a href="http://groovy.codehaus.org/Download"&gt;http://groovy.codehaus.org/Download&lt;/a&gt; w tym uniwersalny instalator i paczki dla innych dystrybucji.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Instalacja - Windows&lt;/span&gt;&lt;br /&gt;&lt;a href="http://dist.codehaus.org/groovy/distributions/installers/windows/nsis/groovy-1.5.6-installer-2.exe"&gt;Instalator Groovy 1.5.6 + Gant 1.3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Test&lt;/span&gt;&lt;br /&gt;Po przeprowadzeniu instalacji pora przetestować GroovyConsole. W Windows powinna pojawić się pozycja w menu star. W obu systemach w linii komend powinno wystarczyć wpisanie &lt;span style="font-weight: bold;"&gt;groovyConsole, &lt;/span&gt;&lt;span&gt;by włączyła się poniższa aplikacja&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt; Wpisujemy w górną część&lt;span style="font-weight: bold;"&gt; print "Hello world"&lt;/span&gt; i klikamy zaznaczony przycisk:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_GEH0YpYIgzE/SIopvB4URHI/AAAAAAAAAJo/XKkvXjCsx3Q/s1600-h/groovy_init.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_GEH0YpYIgzE/SIopvB4URHI/AAAAAAAAAJo/XKkvXjCsx3Q/s400/groovy_init.png" alt="" id="BLOGGER_PHOTO_ID_5227036205452117106" border="0" /&gt;&lt;/a&gt;GroovyConsole jest najprostszym edytorem Groovy, cały kod w edytorze / pliku jest wykonany, a rezultat zwracany.&lt;br /&gt;W Windows kliknięcie na plik z rozszerzeniem .groovy powoduje ich wykonanie. Jak widać Groovy nie wymaga by kod był pisany w metodach.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Linia komend - groovyc&lt;br /&gt;&lt;/span&gt;Kompilator, na razie nie będzie potrzebny.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Linia komend - groovy&lt;br /&gt;&lt;/span&gt;Interpreter&lt;span style="font-weight: bold;"&gt;.&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;groovy Hello.groovy - wykonuje kod z podanego pliku&lt;br /&gt;&lt;/li&gt;&lt;li&gt;groovy -e  " print 'Hello world' " - wykonuje bezpośrednio podany kod&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Linia komend - groovysh&lt;/span&gt;&lt;br /&gt;Interaktywny interpreter.&lt;br /&gt;Interaktywny interpreter to ciekawa pomoc w nauce dostępna w językach takich jak Groovy, Ruby czy Python. A działa to tak:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;kk@kkl:~$ groovysh&lt;br /&gt;Groovy Shell (, JVM: 10.0-b22)&lt;br /&gt;Type 'help' or '\h' for help.&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;groovy:&gt; a = "123" [enter]&lt;br /&gt;===&gt; 123&lt;br /&gt;groovy:&gt; b = 4&lt;br /&gt;===&gt; 4&lt;br /&gt;groovy:&gt; c = 5.0&lt;br /&gt;===&gt; 5.0&lt;br /&gt;groovy:&gt; a+b+c&lt;br /&gt;===&gt; 12345.0&lt;br /&gt;groovy:&gt; "$c - ${b} = ${c-b}"&lt;br /&gt;===&gt; 5.0 - 4 = 1.0 //to jest String !&lt;br /&gt;&lt;/pre&gt;W interpreterze możemy na bierząco tworzyć zmienne (nawet bez ich deklaracji) i przypisywać im dowolne wartości. Po każdej komendzie lub zestawie komend interpreter wykonuje kod i zwraca wynik. Wynikiem jest zawsze wartość ostaniej komendy.&lt;br /&gt;Dla komendy &lt;span style="font-weight: bold;"&gt;1&lt;/span&gt; będzie to 1, dla komendy &lt;span style="font-weight: bold;"&gt;a = 1&lt;/span&gt; będzie to 1, dla komendy &lt;span style="font-weight: bold;"&gt;1;2;3&lt;/span&gt; będzie to 3 a dla komendy &lt;span style="font-weight: bold;"&gt;print 1&lt;/span&gt; będzie to &lt;span style="font-weight: bold;"&gt;null&lt;/span&gt; (po drodze zostanie wypisane 1).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Linijka13 - &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://groovy.codehaus.org/Strings"&gt;GString&lt;/a&gt;&lt;br /&gt;Jeżeli Groovy spotka w String napis postaci &lt;span style="font-weight: bold;"&gt;$nazwa_zmiennej&lt;/span&gt; to wstawi w jej miejsce wartość zmiennej. Jeżeli spotka &lt;span style="font-weight: bold;"&gt;${kod}&lt;/span&gt; to wstawi w to miejsce wykonany kod.&lt;br /&gt;Dalej Stringi można zapisywać w formie:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;"string"&lt;/span&gt; lub &lt;span style="font-weight: bold;"&gt;'string'&lt;/span&gt; - zwykły String&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;/C:\Windows\system /&lt;/span&gt; - String w którym nie trzeba używać \&lt;/li&gt;&lt;li&gt;Stringi na kilka linijek:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;def s = """\&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;String długi na&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;${a[1]} linijki&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"""&lt;/span&gt;&lt;br /&gt;Ten ma dokładnie 2 znaki nowej linii.&lt;br /&gt;&lt;br /&gt;Kod w Stringach zauważa zmiany zmiennych:&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy:&gt; "abcdef".each{print "  $it"}&lt;br /&gt;a  b  c  d  e  f===&gt; abcdef&lt;br /&gt;&lt;/pre&gt;Zmienna &lt;span style="font-weight: bold;"&gt;it&lt;/span&gt; - domyślna zmienna dla funkcji iterujących - przyjmuje wartość kolejnych znaków i za każdym razem nowa wartość jest wstawiana do stringa.&lt;br /&gt;&lt;pre name="code" class="scala"&gt;groovy:&gt; "abcde"[2..4]&lt;br /&gt;===&gt; cde&lt;br /&gt;groovy:&gt; "abcde"[2..-2]&lt;br /&gt;===&gt; cd&lt;br /&gt;groovy:&gt; "abcde"[3..0]&lt;br /&gt;===&gt; dcba&lt;br /&gt;&lt;br /&gt;groovy:&gt; "abcde".size()&lt;br /&gt;===&gt; 5&lt;br /&gt;groovy:&gt; "abcde".length()&lt;br /&gt;===&gt; 5&lt;br /&gt;&lt;br /&gt;groovy:&gt; "abcde" == "ab" + "c" + "de"&lt;br /&gt;===&gt; true&lt;br /&gt;&lt;br /&gt;groovy:&gt; "abcdeabcde" - "abc"&lt;br /&gt;===&gt; deabcde&lt;br /&gt;&lt;/pre&gt;Dla stringów zdefiniowano kilka ciekawych operatorów i funkcji.&lt;br /&gt;Operator &lt;span style="font-weight: bold;"&gt;==&lt;/span&gt; porównuje względem wartości, a nie referencji jak w Java.&lt;br /&gt;Groovy dekoruje istniejące klasy Java (jak string, tablice, kolekcje)  dzięki czemu można wszędzie używać jednej metody &lt;span style="font-weight: bold;"&gt;size() &lt;/span&gt;zamiast raz size, a raz length.&lt;br /&gt;Stringi można też odejmować - zostaje usunięte pierwsze wystąpienie odejmowanego napisu.&lt;br /&gt;&lt;br /&gt;Dodatkowe informacje o &lt;a href="http://groovy.codehaus.org/JN0025-Starting"&gt;String w Groovy&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-1508661878925372438?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/1508661878925372438/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=1508661878925372438' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/1508661878925372438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/1508661878925372438'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/groovy-w-praktyce-part-1-instalacja-i.html' title='Groovy w praktyce - part 1 - instalacja i  String'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_GEH0YpYIgzE/SIopvB4URHI/AAAAAAAAAJo/XKkvXjCsx3Q/s72-c/groovy_init.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7417491378098982434</id><published>2008-07-24T18:49:00.001+02:00</published><updated>2008-11-05T16:05:08.288+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ogólne'/><category scheme='http://www.blogger.com/atom/ns#' term='metodyki'/><title type='text'>PDD - uznana metodyka wytwarzania oprogramowania</title><content type='html'>PDD - Presentation Driven Development ;)&lt;br /&gt;&lt;br /&gt;Zasady pierwotnej wersji PDD:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Błędów się nie usuwa, to zajmuje za dużo czasu, błędy się omija lub wstawia dane na sztywno&lt;/li&gt;&lt;li&gt;Nie rozpatruje się przypadków brzegowych, żadnych&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Nie rozpatruje się nic, czego nie można pokazać - np. wyjątki - nigdzie się ich nie łapie, albo łapie wszystkie i nie pokazuje, że coś poszło nie tak&lt;/li&gt;&lt;li&gt;Działanie nie musi być stabilne, a zarządzanie pamięcią w ogole istnieć - aplikacja ma tylko działać przez czas prezentacji&lt;/li&gt;&lt;li&gt;Jeśli jakieś zadanie zajmuje dużo czasu co powoduje, że oglądający prezentacje lub uruchamiający aplikację musi czekać, to dane do tego zadania wstawia się na sztywno lub wcześniej przygotowuje wyniki (nie konieczne będące efektem działania programu)&lt;/li&gt;&lt;li&gt;Kontrolki i ekrany muszą być ładne, najlepiej lekko animowane&lt;/li&gt;&lt;li&gt;Każdy przycisk ma znaczącą ikonke&lt;/li&gt;&lt;li&gt;Tworzy się jedyną ścieżkę krytyczną - ona musi wyglądać jakby działała i ją sie pokaże&lt;/li&gt;&lt;li&gt;Nie dba się o jaką kolwiek zgodność wsteczną (ale można przygotować port danych ze starej wersji i pokazać jak wygląda w nowej (mówiąc, że dane pochodzą ze starej :) ))&lt;/li&gt;&lt;/ul&gt;Niektóre firmy postanowiły zaadaptować PDD również dla oprogramowania, które trafia do klientów, wtedy pojawiają się pewneo zmiany (obsługuje się niektóre przypadki brzegowe), zasady pozostają podobne. Kilka zmian w PDD dla oprogramowania dostarczanego użytkownikowi:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tworzy się kreatorki ułatwiające pracę na początku, nawet jeśli na dalszych etapach unimożliwiają pracę z powodu złożoności zagadnienia lub ilości danych&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Oprogramowanie ma dobrze wyglądać i bardzo dobrze się sprawdzać dla małych prostych problemów, powinny być dla nich zaproponowane rozwiązania, nie muszą być ogólne&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Nie dba się o skalowalność, czy złożone przypadki&lt;/li&gt;&lt;li&gt;Nie dba się o kompatybilność między wersjami np. wersja 2.0 jest nie kompatybilna z 1.1, a ta jest absolutnie nie zgodna z 1.0&lt;/li&gt;&lt;li&gt;Po wydaniu oprogramowania zbiera się maksymalnie wszelki feedback od użytkowników i zmienia się wersje pierwotną nawet, jeśli użytkownicy chcą zupełnie co innego niż zaplanowano, jeśli wystarczająco duża liczba użytkowników chce coś to można stworzyć kilka różnych produktów&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Niektóre duże firmy z powodzeniem stosują tą metodykę. Jej najefektywniejsza forma jest nazwana $DD - Money Driven Development - stosuje się PDD, ale pierwsza wersja oprogramowania jest dokładną kopią cudzego produktu. Reszta zasad pozostaje bez zmian.&lt;br /&gt;&lt;br /&gt;Nie będe oceniał tutaj PDD i $DD. Pamiętać trzeba tylko o jednym - jeśli firma korzysta z $DD to nigdy nie należy korzystać produkcyjnie z pierwszej wersji oprogramowania, a wersję 2.0 stosować tylko w razie potrzeby po przetestowaniu w rzeczywistym środowisku. Przeważnie wersja 3.0 jest już bardzo udanym produktem.&lt;br /&gt;&lt;br /&gt;ps. Pierwszy raz zauważyłem stosowanie PDD w projekcie tworzonym przez studentów na konkurs, później zauważyłem komercyjne wykorzytanie odkrytej metodyki.  Przypomniałem sobie o PDD z okazji Entity Framework i LINQ to SQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7417491378098982434?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7417491378098982434/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7417491378098982434' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7417491378098982434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7417491378098982434'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/pdd-uznana-metodyka-wytwarzania.html' title='PDD - uznana metodyka wytwarzania oprogramowania'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-4428159907240711983</id><published>2008-07-22T22:57:00.000+02:00</published><updated>2008-07-27T12:23:54.408+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='przegadane'/><title type='text'>Języki na JVM - Scala</title><content type='html'>Scala jest językiem, który moim zdaniem zyska dużo zwolenników. Podobnie jak Groovy został stworzony od podstaw i oparty na Javie. Również tutaj klasy Scala są poprawnymi klasami Java i dziedziczenie jest możliwe. Jednak wzoruje się na językach funkcyjnych takich jak SML i Ocaml, jest silnie, statycznie typowany i to bardzo odróżnia język od JRuby, Jython i Groovy.&lt;br /&gt;&lt;br /&gt;&lt;b id="p_er0"&gt;Scala&lt;/b&gt; &lt;ul id="p_er2"&gt;&lt;li id="p_er3"&gt;Silna i statyczna typizacja - czyli po prostu jest i będzie szybszy niż 3 wcześniej wymienione, a narzędzia potencjalnie mogą być lepsze &lt;/li&gt;&lt;li id="p_er4"&gt;Odgadywanie typu (&lt;a title="type inference" href="http://en.wikipedia.org/wiki/Type_inference" id="gk-e"&gt;type inference&lt;/a&gt;) - zdecydowanie mniej gadatliwy kod niż w Java &lt;/li&gt;&lt;/ul&gt; &lt;ul id="fk6e0"&gt;&lt;li id="nouv"&gt;Czysto obiektowy (absolutnie wszystko jest obiektem)&lt;/li&gt;&lt;li id="nouv0"&gt;Silnie funkcyjny z ładną obsługą powiązanych koncepcji &lt;/li&gt;&lt;li id="xp6-0"&gt;Przeciążanie operatorów&lt;/li&gt;&lt;li id="xe-8"&gt;Pozwala na pewnego rodzaju wielodziedziczenie (mixin,trait)&lt;/li&gt;&lt;li id="jx6e"&gt;Wzorzec singleton jest elementem języka &lt;/li&gt;&lt;/ul&gt; &lt;ul id="fk6e2"&gt;&lt;li id="qqw5"&gt;Kompilowany do bytecodu &lt;/li&gt;&lt;li id="nsf80"&gt;Bezpośrednie korzystanie z typów Java&lt;/li&gt;&lt;li id="qqw50"&gt;Możliwe dziedziczenie po klasach Java&lt;/li&gt;&lt;li id="qqw51"&gt;W przyszłości będą możliwe cykliczne zależności tak jak w Groovy&lt;/li&gt;&lt;li id="ie9c"&gt;Podobno ma lepsze generics niż Java :)&lt;/li&gt;&lt;li id="gl92"&gt;Obsługują adnotacje  &lt;/li&gt;&lt;li id="ie9c1"&gt;Podsumowując możemy używać wszędzie tam gdzie Java, np. w JPA / Hibernate&lt;/li&gt;&lt;/ul&gt; &lt;ul id="odjd0"&gt;&lt;li id="ie9c2"&gt;Wspiera programowanie współbieżne (dzięki aktorom)&lt;/li&gt;&lt;/ul&gt; &lt;ul id="txuj0"&gt;&lt;li id="txuj1"&gt;Jest i będzie szybszy niż Groovy, Ruby/JRuby, Python/Jython, JavaScript etc.&lt;/li&gt;&lt;/ul&gt; &lt;ul id="jvm20"&gt;&lt;li id="jvm21"&gt;Istnieje kompilator Scala dla .Net &lt;/li&gt;&lt;/ul&gt; Przykładowe aplikacje w Scala: &lt;a title="Lift" href="http://demo.liftweb.net/lift/" id="jz4f"&gt;Lift&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Język od początku został zaplanowany jako język funkcyjny, co to oznacza ? Szybki (mimo, że w kompilatory języków funkcyjnych nie zainwestowano tyle czasu co w kompilatory C/C++ to i tak zawsze są blisko czołówki w rankingach wydajności), łatwiejsza obsługa wielordzeniowości, język ładny, kompaktowy, naturalny w obliczeniach matematycznych... &lt;pre name="code" class="scala"&gt;def qsort(lst: List[Int]):List[Int] =&lt;br /&gt; lst match {&lt;br /&gt;    case Nil =&amp;gt; Nil&lt;br /&gt;    case pivot::tail =&amp;gt;  qsort(tail filter { _ &amp;lt; pivot }) ::: pivot ::: qsort(tail filter { _ &amp;gt;= pivot })&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;Oto definicja funkcji (w Scali do zmiennej można przypisywać funkcje, stąd taka notacja). Oczywiście algorytm to &lt;a title="QuickSort" href="http://pl.wikipedia.org/wiki/Sortowanie_szybkie"&gt;QuickSort&lt;/a&gt;.  Teraz bardziej znajoma encja JPA: &lt;pre name="code" class="scala"&gt;@Entity&lt;br /&gt;class SomeClass {&lt;br /&gt; @Id @Generated&lt;br /&gt; var id: Long = -1&lt;br /&gt; var name: String = _&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;a title="Różnice między Java a Scala" href="http://blogs.sun.com/sundararajan/entry/scala_for_java_programmers" id="ismf"&gt;Jest dużo różnic między Java a Scala&lt;/a&gt;, bardzo dużo. Prawie każda koncepcja jest zmieniona lub nowa. Krzywa nauki jest z tego powodu stroma. Przy okazji jeszcze &lt;a title="różnice między Java Groovy i Ruby" href="http://blogs.sun.com/sundararajan/entry/java_groovy_and_j_ruby" id="fwmh"&gt;różnice między Java Groovy i Ruby&lt;/a&gt;.&lt;br /&gt;Studiując różnice nie da się zauważyć, że najłatwiej zrozumieć Groovy, można go wprowadzać stopniowo zaczynając od Java, albo uczyć się od podstaw od razu w nowym stylu. Pewnie dlatego będzie cześciej spotykany od Scali, mimo że Scala jest/będzie szybszym, gotowym na wielordzeniowość - ogólnie scalowalnym językim. Może jednak wprowadza zbyt wiele zmian? Czy zwykłego szarego programiste można nauczyć Scali?&lt;br /&gt;&lt;br /&gt;Wszystkie 4 dotychczas opisane języki posiadają konsolę - interpreter na bieżąco wykonujący podany mu kod, dzięki czemu możemy błyskawicznie uczyć się poznawać konstrukcje języków.&lt;br /&gt;&lt;br /&gt;Jaki powinien być dobry język według mnie? Powinien być silnie i statycznie typowany z refleksją i odgadywaniem typów wszędzie gdzie to możliwe, mieć spójny model semantyczny, który jest zamienialny na sensowny diagramy akcji i sekwencji, pozwalać na styl funkcyjny, mieć domknięcia i definicję rozszerzeń języka.&lt;br /&gt;Myślę, że pojawi się więcej lub zyskają na popularności języki funkcyjne lub tylko trochę "brudne obiektowo" lub nawet czysto funkcyjne, które będą bezpieczne we wszelkich obliczeniach równoległych (więc w sam raz na serwery web, usługi sieciowe, komunikatory i desktopy skoro za parę lat będziemy mieli 64+ rdzeni). Już widać powrót i ponowne wykorzystanie starego języka Erlang. Pewnie będą próby tworzenia systemów operacyjnych w takich językach.  ok, kolejne posty będą bardziej praktyczne.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-4428159907240711983?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/4428159907240711983/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=4428159907240711983' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4428159907240711983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/4428159907240711983'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/scala-jest-jzykiem-ktry-moim-zdaniem.html' title='Języki na JVM - Scala'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-6865882855360150524</id><published>2008-07-22T07:00:00.000+02:00</published><updated>2008-07-27T12:29:26.103+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='przegadane'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Języki skryptowe dla JVM - Groovy, Python, Ruby</title><content type='html'>Maszyna wirtualna Java jest świetną platformą, która udowodniła, że radzi sobie nieźle z nowymi językami. Moim zdaniem na razie liczą się tylko (aż?) 3 języki &lt;a href="http://www.jython.org/Project/"&gt;Jython&lt;/a&gt;, &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; i &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;. W przyszłości na pewno dołączy do nich &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; (&lt;a href="http://scala.sygneca.com/"&gt;wiki&lt;/a&gt;). Są to dojrzałe implementacje, czego nie można powiedzieć o odpowiednikach na platformę .Net.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cechy  wspólne języków&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.jython.org/Project/"&gt;Jython&lt;/a&gt;, &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;, &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Mogą być kompilowane do &lt;a href="http://en.wikipedia.org/wiki/Java_bytecode"&gt;bytecode&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Moga być interpretowane za równo z konsoli jak i w programach Java z plików lub zwykłego String&lt;/li&gt;&lt;li&gt;Mogą wykorzystywać a nawet dziedziczyć po klasach Java&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Są to &lt;a href="http://en.wikipedia.org/wiki/Dynamic_programming_language"&gt;języki dynamiczne&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Pozwalają na przeciążanie operatorów&lt;/li&gt;&lt;li&gt;Mapy, listy itp to natywne konstrukcje języka (np. [a: 1, b: 2] to mapa)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pozwalają na pisanie w stylu funkcyjnym&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Są to języki z typizacją w stylu &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;"Duck Typing"&lt;/a&gt;. Troche więcej na ten temat w stopce.&lt;br /&gt;&lt;br /&gt;Co ciekawe &lt;a href="http://www.jython.org/Project/"&gt;Jython&lt;/a&gt;, &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; są szybsze niż ich natywne wersje pisane w C. Można porównać &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=binarytrees&amp;amp;lang=all"&gt;testy&lt;/a&gt;. W tych testach polecam nie patrzyć na języki spoza JVM, ponieważ procedura testowa nie jest do tego odpowiednia (jak w prawie każdych micro testach). Przy okazji warto zauważyć gdzie jest &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; względem pozostałych trzech i Java.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Jython&lt;/span&gt;&lt;br /&gt;Stara sprawdzona implementacja języka &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; na JVM i robi to dobrze. Python to jeden z 3 "dozwolonych" języków w Google (obok Java i C). Cecha szczególna - wcięcia zamiast nawiasów klamrowych. Google App Engine obsługuje jak na razie tylko Python.&lt;br /&gt;&lt;br /&gt;Znane aplikacje Python: &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt;, &lt;a href="http://plone.org/"&gt;Plone&lt;/a&gt;, &lt;a href="http://www.zope.org/"&gt;Zope&lt;/a&gt;, &lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt; (ostatni warty uwagi nawet jeśli nie chcemy pisać w Python).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JRuby&lt;/span&gt;&lt;br /&gt;&lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; zapewnia bardzo dobrą kompatybilność z Ruby. Ruby to wcale nie taki młody język, kiedyś znany właściwie tylko w Japonii. Praktycznie całą aktualną popularność zawdzięcza powstaniu webframeworka &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;. Sun wpiera implementację JRuby (zatrudnił na stałe kilku jego programistów). Na polskiej Wikipedii znajduje się &lt;a href="http://pl.wikipedia.org/wiki/Ruby_%28j%C4%99zyk_programowania%29"&gt;dobry opis Ruby&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Znane aplikacje Ruby: &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="http://www.basecamphq.com/"&gt;Basecamp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Zarówno JRuby jak i Jython dostarczają bazowe biblioteki znane z natywnych wersji swoich języków jak i pozwalają korzystać z bibliotek Java.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Groovy&lt;/span&gt;&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; nie jest portem istniejącego języka, został pomyślany od początku jako "nowa lepsza Java". Większość kodu napisanego w Javie jest jednocześnie poprawnym(choć strasznie przegadanym) kodem Groovy.&lt;br /&gt;&lt;br /&gt;Groovy ma najlepszą integrację z Javą:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Może być silnie typowany, ale nie musi&lt;/li&gt;&lt;li&gt;Klasy Groovy po kompilacji to stare dobre klasy Java, ale nie każdą metodę można wywołać bezpośrednio (w końcu to język dynamiczny, więc pewne metody nie istnieją w trakcie kompilacji)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Klasy JDK mają dodatkowe metody, zwykle są one szalenie przydatne&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Jako jedyny pozwala na dwustronne dziedziczenie (Java -&gt; Groovy i Groovy -&gt; Java) (a odkąd wspiera łączoną kompilację Java + Groovy, możemy mieć cykliczne zależności (dziedziczenie, zawieranie, korzystanie z metod)  między klasami Java i Groovy, w Scali też kiedyś pojawi się taka możliwość). &lt;/li&gt;&lt;li&gt;Z tych 3 języków tylko Groovy  ma możliwość używania adnotacji i generics, a klasy Groovy są poprawnymi klasami Java, czyli możemy sobie oznaczyć klasę Groovy jako "@Entity" i używać dla nich Hibernate - to wykorzystuje np. Seam)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Znane aplikacje w Groovy: &lt;a href="http://grails.org/"&gt;Grails&lt;/a&gt; (w pewnym sensie (koncepcyjnie) odpowiednik Ruby on Rails, wykorzystuje m.in. Spring i Hibernate)&lt;br /&gt;&lt;br /&gt;Gdy się zna Java nie skryptowego języka prostszego do nauki niż Groovy. Nauka może przebiegać w małych krokach -  zmieniamy rozszerzenie pliku klasy Java na groovy, a później usuwamy niepotrzebny kod dzięki jakiejś nowo poznanej opcji. Wydaje mi się, że nie pozwala również na klasy wewnętrzne i anonimowe (nie pamiętam teraz). Groovy namiętnie używa pewnej koncepcji nazwanej "&lt;a href="http://groovy.codehaus.org/Builders"&gt;builders&lt;/a&gt;". Są to takie mini języki tworzące w banalny sposób wszelkie struktury drzewiaste, czyli XML, Swing, SWT, JSP, ANT... Jest to możliwe w innych językach - tu jest jedną z podstawowych koncepcji i ładnie wygląda. Jeśli utknęło się na starej wersji Java np. 1.4.2 to dalej można wykorzystać większość opcji z Groovy (bez np. adnotacji itp.).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Jeszcze troche o typizacji&lt;br /&gt;&lt;/span&gt;O typizacji mówi się czasem, że jest słaba lub silna, albo statyczna lub dynamiczna, jest z tym sporo &lt;a href="http://en.wikipedia.org/wiki/Programming_language#Type_system"&gt;zamieszania&lt;/a&gt; i nie mam zamiaru opisywać wszystkiego.&lt;br /&gt;Groovy potrafi udawać statyczną typizacje znaną z Java. Domyślnie tak jak reszta ma dynamiczną typizację,  w formie nazywanej &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;"Duck Typing"&lt;/a&gt; mi ten termin bardziej by pasował do &lt;a href="http://caml.inria.fr/"&gt;Ocaml&lt;/a&gt;, no ale trudno - tak się przyjeło. W skrócie wszystkie trzy języki pozwalają na przesyłanie czegokolwiek, gdziekolwiek i tylko w trakcie wykonania mogą się poskarżyć, że dany typ jest nie taki bo &lt;span style="font-weight: bold;"&gt;nie ma funkcji&lt;/span&gt;, którą staramy się wywołać.&lt;br /&gt;&lt;br /&gt;Przykład z &lt;a href="http://onestepback.org/articles/groovy/ducktyping.html"&gt;http://onestepback.org/articles/groovy/ducktyping.html&lt;/a&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;class Duck {&lt;br /&gt; quack() { println "I am a Duck" }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Frog {&lt;br /&gt; quack() { println "I am a Frog" }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;quackers = [ new Duck(), new Frog() ]&lt;br /&gt;for (q in quackers) {&lt;br /&gt; q.quack()&lt;br /&gt;}&lt;/pre&gt;Kod jest poprawny według zasady, że "jeśli coś wygląda jak kaczka i zachowuje się jak kaczka to jest kaczką".&lt;br /&gt;&lt;br /&gt;Można powiedzieć, że tak naprawdę nie wywołujemy metody na obiekcie ale przesyłamy komunikat do obiektu z nazwą funkcji i parametrami, a sam obiekt stara się coś z tym zrobić. Dzięki temu &lt;span style="font-weight: bold;"&gt;możemy obsługiwać funkcje, których nie ma&lt;/span&gt; (powiedzmy, że przeciążamy funkcję MethodMissing i tam każemy dla funkcji o sygnaturze hello_xxx wypisywać xxx na ekran). Pozwala to na tworzenie doskonałych bibliotek o bardzo czytelnym kodzie, ale jednocześnie powoduje, że podpowiadanie składni, statyczna analiza kodu, automatyczne wyszukiwanie błędów, czy zwykła nawigacja po kodzie nigdy nie będą tak dobre jak to jest możliwe w Java czy C#. Jednocześnie m.in. z tego powodu języki te zawsze będą wolniejsze niż Java (istnieje dodatkowy narzut na wykonanie każdej funkcji, utrudnia to też pracę JIT).&lt;br /&gt;Tu znów pewnym wyjątkiem jest Groovy, który pozwala na statyczną typizację, tylko nie wiem czy z tego korzysta do optymalizacji. Z drugiej strony jest jedynym z wymienionych języków, który natywnie wspiera &lt;a href="http://en.wikipedia.org/wiki/Multiple_dispatch"&gt;Multiple Dispatch&lt;/a&gt;, czyli multimethods(&lt;a href="http://blogs.sun.com/sundararajan/entry/multimethods_in_groovy"&gt;dobry krótki przykład&lt;/a&gt;) jak to nazywają w Groovy, a to wymaga badania rzeczywistego typu każdego parametru funkcji i ponownie zmniejsza wydajność kodu.&lt;br /&gt;&lt;br /&gt;Wracając do Ocaml - tu typizacja jest silna i statyczna (z odgadywaniem typów)  mimo to kod często przypomina języki skryptowe. W Ocamlu istnieje coś jak dziedziczenie choć są pewne różnice. Dalej obiekt jest zgodny z  jeśli mają te same metody (w uproszczeniu). Ciekawie to działa w praktyce (tak jak na poprzednim przykładzie ale zwróciło by błąd w trakcie kompilacji, gdyby któraś z klas nie zawierała metody quack()). Typy choć na codzień tego się nie dostrzega to dość złożone zagadnienie, dalszych informacji można szukać w google i na wikipedii pod hasłami &lt;a href="http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29"&gt;covariance i contravariance&lt;/a&gt;. Przydatne do paru problemów z generics i ze zwykłymi tabelami.&lt;br /&gt;&lt;br /&gt;w następnej części opis Scali.&lt;br /&gt;Już teraz specjalnie dla Anke: &lt;a href="http://scala.sygneca.com/patterns/component-mixins"&gt;The Cake Pattern.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-6865882855360150524?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/6865882855360150524/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=6865882855360150524' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/6865882855360150524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/6865882855360150524'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/jzyki-dla-jvm-groovy-python-ruby.html' title='Języki skryptowe dla JVM - Groovy, Python, Ruby'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7881103388627474175</id><published>2008-07-15T23:27:00.000+02:00</published><updated>2008-07-20T19:03:05.268+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><title type='text'>Blogger i Syntax Highlighter</title><content type='html'>Niech pojawia się kolorki.&lt;br /&gt;&lt;pre&gt;&amp;lt;pre name="code" class="java"&gt;&lt;br /&gt;//Komentarz&lt;br /&gt;public Klasa{&lt;br /&gt; public static void main(String args[])&lt;br /&gt; {&lt;br /&gt;   System.out.println("Hello World!"/*jakie to oryginalne*/);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&amp;lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;Zamieni sie na:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;//Komentarz&lt;br /&gt;public Klasa{&lt;br /&gt; public static void main(String args[])&lt;br /&gt; {&lt;br /&gt;   System.out.println("Hello World!"/*jakie to oryginalne*/);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Można to osiągnąć poprzez odwołanie do kodu &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt; z szablonu bloggera. Przechodzę do edycji szablonu bloga (Dostosuj -&gt; Układ -&gt; Edytuj Kod HTML).&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Najpierw potrzebne mi jest miejsce w sieci, gdzie umieszczę &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt; np.  google pages, app engine lub dowolny inny darmowy hosting. Można też wykorzystać istniejące lokalizacje, próbowałem również odwołać się do SVN projektu, jednak plik css coś nie chciał współpracować, dlatego korzystam z googlepages.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;W kodzie html szablonu dodaje kod z odwołaniami do skryptów dla odpowiednich języków (umieszczam kod zaraz przed &amp;lt;/body&gt;). Dodatkowe języki (Scala, Bash etc.) mozna znaleźć w sieci.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;pre name="code" class="html"&gt;&lt;!-- Odniesienia do skryptów --&gt;&lt;br /&gt;&amp;lt;link href="'http://toolsmatter.googlepages.com/SyntaxHighlighter.css'" rel="'stylesheet'" type="'text/css'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shCore.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/js/shBrushScala.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shBrushXml.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shBrushShell.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shBrushJava.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shBrushSql.js'/"&gt;&lt;br /&gt;&amp;lt;script language="'javascript'" src="'http://toolsmatter.googlepages.com/shBrushJScript.js'/"&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- Uruchomienie skryptów --&gt;&lt;br /&gt;&amp;lt;script language="'javascript'"&gt;&lt;br /&gt;dp.SyntaxHighlighter.ClipboardSwf = 'http://toolsmatter.googlepages.com/clipboard.swf';&lt;br /&gt;dp.SyntaxHighlighter.BloggerMode();&lt;br /&gt;dp.SyntaxHighlighter.HighlightAll('code');&lt;br /&gt;&amp;lt;/script&gt;&lt;br /&gt;&lt;/pre&gt;Minus takiego podejścia jest prosty - zmiana szablonu wymaga odrobine pracy. Nie zmienia się szablonu często więc jest to ok. Jednak jedno wklejenie kodu uświadamia mi, ze ten blog potrzebuje szerszego szablonu.&lt;br /&gt;&lt;br /&gt;ps. w przypadku kodu xml / html, trzeba zamieniać przed wysłaniem '&amp;lt;' na '&amp;amp;lt;'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7881103388627474175?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7881103388627474175/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7881103388627474175' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7881103388627474175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7881103388627474175'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/blogger-i-syntax-highlighter.html' title='Blogger i Syntax Highlighter'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-7851761370265762174</id><published>2008-07-11T23:56:00.000+02:00</published><updated>2008-07-15T23:15:56.865+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ogólne'/><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><title type='text'>Blog i kolorowanie kodu</title><content type='html'>Kobiety widzą kolory. A mężczyźni ? Dla mężczyzn łososiowy to yyy smak, fiołkowy może być zapach, pomarańcza to owoc, a kremowy? Masz na myśli kremową konsystencje chyba?&lt;br /&gt;No dobrze, może płeć mniej piękną nie potrafi doradzić, czy do niebieskich oczu lepiej pasują lazurowe, czy turkusowe kolczyki jednak kilka kolorów nazwać umiemy! Podobno statystycznie od 6 do 8, a zdarzają się tacy co dobiją do 16. Pomijam oczywiście w statystyce artystów, im pokrewnych i spowinowaconych.&lt;br /&gt;&lt;br /&gt;A ile kolorów rozróżniają programiści ?&lt;br /&gt;&lt;br /&gt;Hmm, String, komentarz, identyfikator, słowo kluczowe, operator, liczba. Razem 6 - jak widać nie odbiegamy od przeciętnej.&lt;br /&gt;&lt;br /&gt;Dobrze, a jak zmusić by na blogu kod był w kolorach?&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Kopiować kolorowy kod z edytora (jako HTML)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Skorzystać z uniwersalnego skryptu zamieniającego kod na pokolorowany HTML&lt;/li&gt;&lt;li&gt;Skorzystać ze skryptu JavaScript, który koloruje kod po stronie klienta&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;ad 1.&lt;br /&gt;Używany edytor kodu musiałby umieć bezpośrednio zapisać kod w HTML lub (co częstrze) pozwolał na skopiowanie kolorowego kodu np. do Word, z którego można wysłać notkę bezpośrednio na blog lub zapisać do HTML. W takim rozwiązaniu każdy język będzie najpewniej miał własny styl kolorowania.&lt;br /&gt;&lt;br /&gt;ad 2.&lt;br /&gt;np. &lt;a href="http://quickhighlighter.com/"&gt;Quick Highlighter&lt;/a&gt; który obsługuje znacznie więcej języków niż jestem w stanie nazwać. Nawet Apache Log File, Lotus Script, czy robots.txt ! A zresztą po co pisać - menu skopiowane ze strony:&lt;br /&gt;&lt;br /&gt;&lt;legend&gt;Select a language&lt;/legend&gt;&lt;br /&gt;   &lt;select id="language" name="language"&gt;&lt;br /&gt;    &lt;option value="abap"&gt;ABAP&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="actionscript"&gt;ActionScript&lt;/option&gt;&lt;br /&gt;    &lt;option value="actionscript3" class="sublang"&gt;ActionScript 3&lt;/option&gt;&lt;br /&gt;    &lt;option value="ada"&gt;Ada&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="apache"&gt;Apache Log File&lt;/option&gt;&lt;br /&gt;    &lt;option value="applescript"&gt;AppleScript&lt;/option&gt;&lt;br /&gt;    &lt;option value="asm"&gt;ASM (NASM based)&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="asp"&gt;ASP&lt;/option&gt;&lt;br /&gt;    &lt;option value="autoit"&gt;AutoIT&lt;/option&gt;&lt;br /&gt;    &lt;option value="bash"&gt;Bash&lt;/option&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;option value="basic4gl"&gt;Basic 4gl&lt;/option&gt;&lt;br /&gt;    &lt;option value="blitzbasic"&gt;BlitzBasic&lt;/option&gt;&lt;br /&gt;    &lt;option value="bnf"&gt;Backus-Naur form&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="c"&gt;C&lt;/option&gt;&lt;br /&gt;    &lt;option value="c_mac"&gt;C for Macs&lt;/option&gt;&lt;br /&gt;    &lt;option value="caddcl"&gt;CAD DCL&lt;/option&gt;&lt;br /&gt;    &lt;option value="cadlisp"&gt;CAD Lisp&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="cfdg"&gt;CFDG&lt;/option&gt;&lt;br /&gt;    &lt;option value="cfm"&gt;ColdFusion&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="cpp"&gt;C++&lt;/option&gt;&lt;br /&gt;    &lt;option value="cpp-qt" class="sublang"&gt;&amp;nbsp;&amp;nbsp;C++/QT&lt;/option&gt;&lt;br /&gt;    &lt;option value="csharp"&gt;C#&lt;/option&gt;&lt;br /&gt;    &lt;option value="css"&gt;CSS&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="d"&gt;D&lt;/option&gt;&lt;br /&gt;    &lt;option value="delphi"&gt;Delphi&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="diff"&gt;Diff&lt;/option&gt;&lt;br /&gt;    &lt;option value="div"&gt;DIV&lt;/option&gt;&lt;br /&gt;    &lt;option value="dos"&gt;DOS&lt;/option&gt;&lt;br /&gt;    &lt;option value="dot"&gt;GraphViz&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="eiffel"&gt;Eiffel&lt;/option&gt;&lt;br /&gt;    &lt;option value="fortran"&gt;Fortran&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="freebasic"&gt;FreeBasic&lt;/option&gt;&lt;br /&gt;    &lt;option value="genero"&gt;Genero (4GL)&lt;/option&gt;&lt;br /&gt;    &lt;option value="gettext" &gt;GetText&lt;/option&gt;&lt;br /&gt;    &lt;option value="glsl" &gt;Glsl&lt;/option&gt;&lt;br /&gt;    &lt;option value="gml"&gt;GML&lt;/option&gt;&lt;br /&gt;    &lt;option value="groovy"&gt;Groovy&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="haskell"&gt;Haskell&lt;/option&gt;&lt;br /&gt;    &lt;option value="html4strict"&gt;HTML (4.0.1)&lt;/option&gt;&lt;br /&gt;    &lt;option value="idl"&gt;Uno IDL&lt;/option&gt;&lt;br /&gt;    &lt;option value="ini"&gt;Ini&lt;/option&gt;&lt;br /&gt;    &lt;option value="inno"&gt;Inno&lt;/option&gt;&lt;br /&gt;    &lt;option value="io"&gt;IO&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="java"&gt;Java&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="java5" class="sublang"&gt;&amp;nbsp;&amp;nbsp;Java 5&lt;/option&gt;&lt;br /&gt;    &lt;option value="javascript"&gt;Javascript&lt;/option&gt;&lt;br /&gt;    &lt;option value="kixtart"&gt;Kixtart&lt;/option&gt;&lt;br /&gt;    &lt;option value="latex"&gt;LaTeX&lt;/option&gt;&lt;br /&gt;    &lt;option value="lisp"&gt;Lisp&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="lotusformulas"&gt;Lotus Formulas&lt;/option&gt;&lt;br /&gt;    &lt;option value="lotusscript"&gt;Lotus Script&lt;/option&gt;&lt;br /&gt;    &lt;option value="lua"&gt;Lua&lt;/option&gt;&lt;br /&gt;    &lt;option value="m68k"&gt;M68k&lt;/option&gt;&lt;br /&gt;    &lt;option value="matlab"&gt;Matlab&lt;/option&gt;&lt;br /&gt;     &lt;br /&gt;    &lt;option value="mirc"&gt;mIRC&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="mpasm"&gt;MPASM&lt;/option&gt;&lt;br /&gt;    &lt;option value="mxml"&gt;MXML&lt;/option&gt;&lt;br /&gt;    &lt;option value="mysql"&gt;MySQL&lt;/option&gt;&lt;br /&gt;    &lt;option value="nsis"&gt;NullSoft Installer&lt;/option&gt;&lt;br /&gt;    &lt;option value="objc"&gt;Objective C&lt;/option&gt;&lt;br /&gt;    &lt;option value="ocaml"&gt;OCaml&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="ocaml-brief" class="sublang"&gt;&amp;nbsp;&amp;nbsp;OCaml (Brief)&lt;/option&gt;&lt;br /&gt;    &lt;option value="oobas"&gt;Openoffice.org BASIC&lt;/option&gt;&lt;br /&gt;    &lt;option value="oracle8"&gt;Oracle 8&lt;/option&gt;&lt;br /&gt;    &lt;option value="pascal"&gt;Pascal&lt;/option&gt;&lt;br /&gt;    &lt;option value="per"&gt;Per (4GL)&lt;/option&gt;&lt;br /&gt;    &lt;option value="perl"&gt;Perl&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="php" selected="selected"&gt;PHP&lt;/option&gt;&lt;br /&gt;    &lt;option value="php-brief" class="sublang"&gt;&amp;nbsp;&amp;nbsp;PHP (Brief version)&lt;/option&gt;&lt;br /&gt;    &lt;option value="plsql"&gt;PL/SQL&lt;/option&gt;&lt;br /&gt;    &lt;option value="python"&gt;Python&lt;/option&gt;&lt;br /&gt;    &lt;option value="qbasic"&gt;QBasic/QuickBASIC&lt;/option&gt;&lt;br /&gt;    &lt;option value="rails"&gt;Rails&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="reg"&gt;Windows Registry&lt;/option&gt;&lt;br /&gt;    &lt;option value="robots"&gt;robots.txt&lt;/option&gt;&lt;br /&gt;    &lt;option value="ruby"&gt;Ruby&lt;/option&gt;&lt;br /&gt;    &lt;option value="sas"&gt;SAS&lt;/option&gt;&lt;br /&gt;    &lt;option value="scala" &gt;Scala&lt;/option&gt;&lt;br /&gt;    &lt;option value="scheme"&gt;Scheme&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="sdlbasic"&gt;SDLBasic&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="smalltalk"&gt;Smalltalk&lt;/option&gt;&lt;br /&gt;    &lt;option value="smarty"&gt;Smarty&lt;/option&gt;&lt;br /&gt;    &lt;option value="sql"&gt;SQL&lt;/option&gt;&lt;br /&gt;    &lt;option value="tcl"&gt;TCL&lt;/option&gt;&lt;br /&gt;    &lt;option value="text"&gt;Plain text&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="thinbasic"&gt;thinBasic&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="tsql"&gt;T-SQL&lt;/option&gt;&lt;br /&gt;    &lt;option value="vb"&gt;Visual Basic&lt;/option&gt;&lt;br /&gt;    &lt;option value="vbnet"&gt;VB.NET&lt;/option&gt;&lt;br /&gt;    &lt;option value="verilog"&gt;Verilog&lt;/option&gt;&lt;br /&gt;    &lt;option value="vhdl"&gt;VHDL&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="visualfoxpro"&gt;Visual FoxPro&lt;/option&gt;&lt;br /&gt;    &lt;option value="winbatch"&gt;Winbatch&lt;/option&gt;&lt;br /&gt;&lt;br /&gt;    &lt;option value="xml"&gt;XML&lt;/option&gt;&lt;br /&gt;    &lt;option value="xpp"&gt;X++&lt;/option&gt;&lt;br /&gt;    &lt;option value="z80"&gt;Z80 Assembler&lt;/option&gt;&lt;br /&gt;   &lt;/select&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Z ciekawych opcji - nazwy klas dla Javy mają automatycznie przypisany link, który pozwala na wyszukiwanie ich w google. Przy takim rozwiązaniu styl jest konsekwenty, a linie ponumerowane.&lt;br /&gt;&lt;br /&gt;ad 3.&lt;br /&gt;Najwygodniejsze rozwiązanie, po integracji wystarcza jeden tag, wybór języka i sam kod.&lt;br /&gt;Czyli w przybliżeniu taki html:&lt;br /&gt;&lt;pre style="font-family: courier new;"&gt;&lt;br /&gt;&amp;lt;kod jezyk="obslugiwanyJezyk"&gt;&lt;br /&gt;   printf "Hello World"&lt;br /&gt;   ...&lt;br /&gt;&amp;lt;/kod&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Zamienia się na kolorowy kod. I to wszystko na koszt klienta.&lt;br /&gt;Właśnie tak działa &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt;, istnieją &lt;a href="http://wordpress.org/extend/plugins/syntaxhighlighter/"&gt;pluginy do WordPress&lt;/a&gt; i innych platform, które pozwalają na prostą integrację z blogiem. Są też inne rozwiązania np. &lt;a href="http://softwaremaniacs.org/soft/highlight/en/"&gt;highlight.js&lt;/a&gt;, czy &lt;a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html"&gt;google-code-prettify&lt;/a&gt;. Nie widze pluginu do Bloggera, wieć następny post będzie o integracji wybranego skryptu z Bloggerem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-7851761370265762174?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/7851761370265762174/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=7851761370265762174' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7851761370265762174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/7851761370265762174'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/07/blog-i-kolorowanie-kodu.html' title='Blog i kolorowanie kodu'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5791022022546268432.post-5448205157561181028</id><published>2008-07-11T08:30:00.000+02:00</published><updated>2008-07-10T23:34:27.321+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ogólne'/><title type='text'>init()</title><content type='html'>Koniec sesji to dobra okazja by stworzyć blog. Ten ma na celu pewną systematyzację moich poczynań przy zabawie, a czasem walce z technologiami.&lt;br /&gt;&lt;br /&gt;W związku z moją pracą dyplomową, na blogu najpewniej pojawi się sporo z zakresu  języków dziedzinowych, modelowania, transformacji między modelami, tworzeniu kodu na podstawie modeli etc. Temat jest spory, a blog wymusza pewien porządek, jest trwały i może przekona mnie do systematycznej pracy.&lt;br /&gt;&lt;br /&gt;Poniżej lista skrótów, które mają szansę się pojawić, jeśli ktoś jest zainteresowany jakimś tematem to czekam na sugestie.&lt;br /&gt;&lt;br /&gt;! - prawie pewne&lt;br /&gt;? - mało prawdopodobne&lt;br /&gt;&lt;br /&gt;Modelowanie&lt;br /&gt;&lt;ul&gt;&lt;li&gt;UML!  czyli najlepszy i najgorszy zarazem język do modelowania&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ecore&lt;/li&gt;&lt;li&gt;openArchitetureWare!&lt;/li&gt;&lt;li&gt;ATL?&lt;/li&gt;&lt;li&gt;Eclipse EMF, bo całe Eclipse jest Model Driven!&lt;/li&gt;&lt;li&gt;ADM, MDA na opak, czyli jak z istniejącego kodu coś wyciągnąć, albo przetłumaczyć na inny&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;DSL*&lt;br /&gt;&lt;ul&gt;&lt;li&gt;GMF,           czyli własny język w 2 tygodnie&lt;/li&gt;&lt;li&gt;MS DSL Toolkit, czyli własny język w tydzień&lt;/li&gt;&lt;li&gt;ANTLR,       czyli własny język w weekend&lt;/li&gt;&lt;li&gt;oAW XText, czyli własny język w godzinę&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;* Czasy nie poparte żadnymi badaniami ;)&lt;br /&gt;&lt;br /&gt;Web&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JSF + Seam! lub Shale?&lt;/li&gt;&lt;li&gt;Struts2&lt;/li&gt;&lt;li&gt;Spring MVC + WebFlow&lt;/li&gt;&lt;li&gt;Stripes&lt;/li&gt;&lt;li&gt;Wicket?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ASP.NET MVC&lt;/li&gt;&lt;li&gt;Flex&lt;/li&gt;&lt;li&gt;GWT&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Frameworki&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Spring IoC&lt;/li&gt;&lt;li&gt;Eclipse RCP&lt;/li&gt;&lt;li&gt;Google App Engine&lt;/li&gt;&lt;li&gt;ADO.NET Entity Framework, czyli czego w Javie się nie da, co da się w C# i czemu należy czekać na wersję 2.0 w przypadku produktów Microsoft&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Języki&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Groovy!  po co generować setery...&lt;/li&gt;&lt;li&gt;Scala?     bo silna typizacja to lepsze (potencjalnie) narzędzia i prędkość&lt;/li&gt;&lt;li&gt;C# 3.0,    styl funkcyjny i jak zrobić własny Linq, czyli dlaczego C# zaczyna mi się podobać&lt;/li&gt;&lt;li&gt;Erlang?   bo i tak będziemy mieli kilkadziesiąt rdzeni | najprostszy z języków ?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;AspectJ? bo aspekty są dobre&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Toolbox&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Małe i duże narzędzia przydatne na co dzień&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Wygląda na to, że tematów starczy mi na kilka najbliższych lat...&lt;br /&gt;Lista pozwoli na pamiętanie pomysłów, a blog ma też na celu uświadomienie mi, że niestety wszystkiego poznać i opisać nie można...&lt;br /&gt;&lt;br /&gt;Teraz pora na wybór.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5791022022546268432-5448205157561181028?l=toolsmatter.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://toolsmatter.blogspot.com/feeds/5448205157561181028/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5791022022546268432&amp;postID=5448205157561181028' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/5448205157561181028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5791022022546268432/posts/default/5448205157561181028'/><link rel='alternate' type='text/html' href='http://toolsmatter.blogspot.com/2008/06/init.html' title='init()'/><author><name>Krzysiek</name><uri>http://www.blogger.com/profile/03930625629870670860</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
