Groovy Methodenauswahl Gotcha

Groovy hat mich schon wieder erwischt. Da wollte ich doch nur eine Methode aufrufen die wahlweise einen String oder ein Array von Strings erwartet, jedoch war das Ergebnis eher überraschend.

Man nehme:

public class CallString {
private String[] books = new String[64]
public void setBook(String book) {
System.out.println(„set book string“)
this.books[0] = book
}
public void setBook(String[] inBooks) {
System.out.println(„set book array“)
for (int i = 0; i < inBooks.length && books.length; ++i) { this.books[i] = inBooks[i] } } public String toString() { return "["+ books.findAll {it != null}.join(", ") +"]" } } [/sourcecode] Und rufe folgendes auf: [sourcecode language='java'] CallString o = new CallString(); o.setBook("The Book") println o $ groovy call.groovy set book string [, The Book] [/sourcecode] Okay das ist noch wie erwartet. Allerdings ist der Mensch ja faul und verwendet gerne die abgekürzte schreibweise: [sourcecode language='java'] CallString o = new CallString(); o.book = "The Book" println o $ groovy call.groovy set book array [, T, h, e, , B, o, o, k] [/sourcecode] Das ist nun wirklich nicht das was ich erwartet habe und hat mich auch ein wenig Zeit gekostet. Das selbe passiert übrigens auch wenn CallString in Java geschrieben ist.

Wie dem auch sei scheint es wie auch bereits beim vorherigen Groovy Map Gotcha mit der Magie hinter dem Methodenzugriff per „.“ zu stecken und man sollte direkt die gewünschten Methoden aufrufen wenn man auf der sicheren Seite sein will – oder muss wissen was man tut.

Groovy Map Gotcha

Ich schaue mir derzeit Groovy an und bin dabei auf etwas gestoßen was mich doch ziemlich verwirrt hat. Es geht um das Verhalten des .class Attributs (?) von Objekten (Wobei sich dies hinterher als „Feature“ der groovy Maps heraugestellt hat).


groovy:000> [1, 2, 3].class
===> class java.util.ArrayList
// Wie erwartet


groovy:000> [a: 1, b: 2, c: 3].class
===> null
// WTF?


groovy:000> [a: 1, b: 2, c: 3].getClass()
===> class java.util.LinkedHashMap
// Hmm, das scheint aber zu funktionieren

Die Lösung dieses Mysteriums hat sich mir dann erschlossen als ich herausgefunden habe dass man auf Maps mittels Schreibweise: mymap.key zugreifen kann.


groovy:000> [a: 1, b: 2, class: 3].class
===> 3
// Was sonst ... :)

Wir lernen also:

  1. Benutze getClass()
  2. Magie hat nicht nur die Leute im Mittelalter verwirrt
  3. Groovy hat einige Gotchas