Clojure store persistent data structures gotcha – load-file size limit

In clojure – the data structure and their default representation are suited as readable and portable format to persist data. But there is a small pitfall in using it.

Data Structure example:

{
  :request-time 2636,
  :status 200,
  :headers
  {
    "server" "Server",
    "content-encoding" "gzip",
  }
}

Be aware that this function is intended to load code only. If your data structures or a string in them grow bigger than around 65,535 it crashes.

Exception similar to:

java.lang.ClassFormatError: Unknown constant tag 49 in class file parse$eval13

Please use read-string instead.

Example: (read-string (slurp "data.clj"))

Source: Rich Hickey on google groups Google Groups

Advertisements

MySQL GROUP BY Gotcha

Ich will hier kurz ein Gotcha vorstellen, das bei der Verwendung von Group By unter MySQL auftreten kann und dann ein Gegenbeispiel in PostgreSQL bringen.

Nehmen wir folgende Tabelle an:


O_Id OrderDate OrderPrice Customer
1 2008/11/12 1000 Hansen
2 2008/10/23 1600 Nilsen
3 2008/09/02 700 Hansen
4 2008/09/03 300 Hansen
5 2008/08/30 2000 Jensen
6 2008/10/04 100 Nilsen

Dann wäre das folgende Query gültig und hilfreich um die Summe für einen Kunden zu bestimmen:


$ SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer
Customer SUM(OrderPrice)
Hansen 2000
Nilsen 1700
Jensen 2000

Hierbei befinden sich alle angezeigten Felder in dem GROUP BY Ausdruck oder in einer Aggregatfunktion.

Unter MySQL ist jedoch auch folgendes möglich:


SELECT * FROM Orders GROUP BY Customer

Hierbei würde nach Kunde Gruppiert, sowie alle anderen Felder angezeigt werden. Allerdings ist hierbei *nicht definiert welche Werte die nicht gruppierten Felder haben!* Siehe dazu auch MYSQL: GROUP BY mit versteckten Feldern. Hier wird dies „Feature“ genannt und muss explizit deaktiviert werden …

Unter PostgreSQL bekommt man jedoch standardmäßig folgende Fehlermeldung die einem vor so manchem Fehler bewahren kann:


$ SELECT * FROM Orders GROUP BY Customer;
ERROR: column "Orders.O_Id" must appear in the GROUP BY clause or be used in an aggregate function

Quellen:

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