Posts in category software

SSL Certificate Trouble

If you should ever stumble upon this bug, consider yourself very lucky that I have found the solution to this already, because it took me _AGES_ to figure this out. No shit.

So here's the problem: We used a self signed certificate on on of our servers and curl and all tools relying on curl just couldn't connect to this server at all (with certificate validation). Despite the fact that the root certificate that signed the server certificate was happily in my keychain and marked as trusted.

The solution first: Turns out that the Keychain will eat certificates in many formats, specifically it supports DER and PEM. curl however can't use the DER certificate in the keychain and just reports it as missing. Exporting the certificate, converting it to PEM and then reimporting it (making sure to remove the DER version beforehand) fixed it.

I converted the file with this command

openssl x509 -inform DER -in some.ser.ver.der -out some.serv.ver.pem

Here's some of the error messages I got:

% curl -I https://some.serv.ver -v
* About to connect() to some.serv.ver port 443 (#0)
*   Trying some.ip... connected
* Connected to some.ser.ver (some.ip) port 443 (#0)
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

If you hit this brick wall - hope this helps you too.

Objective-C Metaprogrammierung: Blöcke zu Methoden

Die Ruby Welt verwendet Blöcke (Closures) liebend gerne für alles mögliche. Zum Beispiel als Builder-Methapher um Baumstrukturen (XML, GUI's, HTML, Tests) in der Sprache hinzuschreiben und dann nur noch in die Target-Sprache zu rendern.

Das sieht in Tests zum Beispiel so aus:

describe "something" do

  it "should do fnord" do
    someObject.should be_fnordy
  end

end

Der Trick dabei ist das alles von do bis end jeweils ein Block ist der von der Methode describe oder it dann in eine UnitTest Klassenstruktur eingehängt wird um dann später als 'ganz normale' unit tests ausgeführt zu werden.

Jetzt wo Objective-C auch Blöcke unterstützt (ok, die können natürlich weniger als das Ruby Equivalent) müsste das eigenltich auch gehen - und siehe da mit  Cedar gibt es auch schon einen ersten Versuch  RSpec in Objective-C nachzubauen.

Well und daher habe ich mir mal angeschaut wie weit man denn kommt wenn man in Objective-C einen Block in eine Instanz-Methode umwandeln will.

Gleich vorneweg - das Typ-System von Objective-C macht mir hier einen kleinen Strich durch die Rechnung - ich habe es nicht geschafft einen Block nicht direkt als Funktions-pointer verwenden.

Aber mit etwas Umweg geht es doch.

Der Trick ist das Blöcke auch id's sein können, d.h. man kann sie bequem in ein NSMutableDictionary packen.

Also brauche ich auf meiner Klasse nur ein Dictionary, speichere die Blöcke darin mit dem Namen der Methode ab und baue mir einen generischen Dispatcher-IMP der den Selector (zweites unsichtbares Argument jeder Objective-C Methode) verwendet um den Block aus aus dem Dictionary zu ziehen und führe ihn dann einfach aus.

So sieht dass dann aus

Die schönsten Testsuiten

Sowas wünsche ich mir auch mal für andere Programmiersprachen. Eine ständig aktuelle Hitliste der schönsten Testsuiten von Open Source software.

 Sowas hier - aber systematisch und crowdsourced immer aktuell.

Hach, man kann träumen. :-)

jQuery editInPlace

Well, I just finished some major reworking of that jQuery plugin, so now it has a real testsuite and conforms to the  jQuery Plugin Guidelines and doesn't pollute the core prototypes (of String) anymore.

There are a few new features, most prominent the ability to define a class to apply for the hover effect (so you can style the hover in css instead of having to hand in the colors directly and more control over the way errors are presented so it is easier to embed into bigger applications.

So enjoy  the demo and  the download while they are hot, and keep a bookmark to  the project homepage. :)

Stuff I'd like to note:

  •  JSpec rocks, writing tests with it is a breeze. The DOM Testrunner they have could use some work though to become even more usefull
  • Writing the tests with no dom insertion is a _great_ technique to get a fast testsuite where you can almost guarantee that it has no test-ordering issues.
  • jQuery allows you to almost completely drive the interaction with the editor as a user would, making it almost like an acceptance test (and with very little dependency on the internal working of the editor.
  • Refactoring JavaScript Code is hard if you don't have a testsuite. My Advice: Break it down into smaller bits. I found it incredibly hard to refactor larger pieces of the code, as not having a testsuite means there's no way you know what still works. :/

Softwareentwicklung als Kooperatives Spiel

Das ist ein steinalter  Vortrag von Alistair Cockburn (gesprochen Co-Burn) in dem er darlegt wieso er findet das das eine sehr gute Sichtweise auf Softwareprojekte ist.

Der Vortrag ist schon 10 Jahre alt - und trotzdem finde ich ihn sehr Aktuell.

Lesenswert!

IE 8 oh IE 8, wärst Du doch kein IE 7...

Heute bin ich auf einen sehr interessanten Bug gestoßen - im IE natürlich. Genauer genommen im IE 8.

Folgendes ist passiert: Wir hatten ein Problem mit dem Rendering einer Webapplikation - dort fehlte mal wieder ein Teil das eigentlich hätte da sein sollen. Stellt sich heraus, dass auf manchen der Rechner der IE 8 die Seite im IE 7 Kompatibilitätsmodus gerendert hat - ok wir hatten also eigentlich einen Bug mit dem IE 7 der das CSS nicht vertragen hat. Soweit so gut.

Mysteriös war das ganze, denn es ließ sich auf verschiednen Rechnern nicht reproduzieren. Dabei verwendeten wir sogar die gleichen images ( VirtualBox ich liebe dich).

Ok, wir sind also irgendwie auf manchen Rechnern in den IE 7 Kompatibilitätsmodus gerutscht. Wirklich Lustig wurde dass als wir auf  dieser Seite auf die Erklärung gestoßen sind:

IE 8 kann nämlich den IE 7 emulieren. Aus 'Kompatibilitätsgründen'. Und weil das natürlich total kompatibel sein muss hat Microsoft das so eingestellt dass alle Intranetseiten automatisch im IE 7 Modus gerendert werden - natürlich ohne einen Knopf mit dem man das abstellen kann. (Andersrum gibt es schon einen…)

Das geile daran: IE erkennt Intranetseiten nicht an der IP, sondern an der Domain! Weil das nicht anders geht! [sic] Und da auf dem anderen Rechner die Webseite per IP aufgerufen wurde wurde das Problem da nicht sichtbar…

Überhaupt ist die Implementierung dieses Kompatibilitätsmodus eine einzige Katastrophe.

  1. Der Modus aktiviert sich automatisch für Intranet-Webseiten
  2. Er lässt sich für diese nicht deaktivieren
  3. IE merkt sich welche Webseiten der User irgendwann schon einmal (vielleicht aus versehen) in den Kompatibilitätsmodus geschaltet hat - aber löscht dieses Wissen wenn man die History löscht.
  4. Jede Webseite kann diese User-Einstellung überschreiben, indem sie einen meta-tag setzt
    1. und dann wird die User-Einstellung auch gleich komplett gelöscht! (*rotflol*)
    2. Man kann über den Meta-Tag nur einstellen dass man gerne eine IE 8 Emulation hätte - wenn der IE 9 dann herauskommt darf man also wieder ran und noch mehr Meta-Tags definieren… (*kotz*)

Also wirklich verkackt auf der ganzen Linie - eine  Lektüre des Original-Artikels ist wirklich empfohlen. :)

Git Handarbeit II: Submodules

Noch so eine Stelle an der GIT einem extra viel Handarbeit aufdrückt. Submodules.

Erst mal die Idee (die eigentlich ganz gut ist): Oft will man Teile der Software (Frameworks, Plugins, ...) eigentlich als eigenes Projekt in einem eigenen Repository entwickeln. Und das ist GUT (TM).

Daher bieten eigentlich alle etwas fortgeschritteneren Versionskontrollsysteme irgend eine Möglichkeit solche externen Repositories einzubinden, damit man es einfach hat an aktuelle Versionen dieses Codes heranzukommen.

Dazu gibt es jetzt in der Regel zwei Ansätze: Entweder man verlinkt einfach auf den HEAD des anderen Repos oder auf eine bestimmte Revision. Letzteres ist im allgemeinen Fall zwingend, denn sonst hat man nie die Chance einen alten Build auch tatsächlich exakt wieder herzustellen - im Speziellen Fall ist ersteres aber sehr Praktisch, wenn man z.B. aus einem globalen Repository einfach Teile an verschiedenen Stellen einblenden möchte, damit sie im Repo nur einmal, im Checkout aber mehrfach oder einfach an einer anderen Stelle erscheinen.

SVN macht das mit  svn:external attributen die sowohl auf HEAD als auch auf spezifische Revisionen verlinken können. HG macht das mit  forests ( noch eine extension), bzr weiß ich nicht und git macht das mit submodules.

Bei SVN hat man noch den Nachteil das es, weil es branches und tags nur als Verzeichnisse kennt natürlich auch Handarbeit erfordert, das hießt, dass man beim Taggen von HEAD z.B. nicht automatisch von dem link auf einen anderen HEAD auf einen Link auf eine spezifische Revision umschalten kann. Das gibt dann das Ergebnis, dass man oft im Tag auf den HEAD eines anderen Teils des Repos verweist. Gratulation! Und wiedererzeugbare Builds ade.

Besonders geärgert haben mich aber die GIT-Submodules. Zuerst: Die sind auch ein Plugin - und in bester GIT manier gibt es natürlich überhaupt keine integration in die anderen Kommandos.

Das bedeutet schon mal das man nicht ein Repository pullen kann um danach einen Build zu machen - NEIN, man muss erst merken dass man noch die Submodules benötigt und dann git submodule init && git submodule update eingeben.

Yeah. Give me useless extra steps!

Es wird aber noch besser, weil es keine Intgegration gibt, sieht man natürlich mit git status nicht das es in einem submodule Änderungen gab. Ok, das stimmt nicht ganz. Man sieht nicht dass es in einem submodule uncommittete Änderungen gab. Commitet man dann nämlich dort, dann sieht man im parent repository dass sich etwas verändert hat - und dass muss man dann nochmal committen.

Yeah. Give me useless extra steps!

Auch schön, wenn man z.B. von GitHub ein Projekt mit Submodules auscheckt, dann zeigt der Origin des Projekts auf GitHub - sinnvoll, weil dahin wird man seine eigenen changes ja schieben wollen, damit Upstream sie mergen kann. Nicht so bei submodules - dort zeigt der origin natürlich auf das ursprüngliche Projekt - auf das man natürlich regelmäßig nicht pushen kann/will. Man muss also einen eigenen branch des submodules auf GitHub anlegen und dann das bei sich von hand als Branch registrieren und dann immer daran denken das im submodule natürlich nicht origin sonder ein anderer name für den parent branch gilt.

Yeah. Give me useless extra steps!

Hach, und natürlich sind GIT submodules IMMER auf eine bestimmte Revision gebunden - tollerweise auch gleich ohne mitzubekommen auf welchem Branch diese jetzt liegt. Das heißt dass man sowieso dort drin per default nix committen kann. Man muss also in jedem fall einen eigenen Remote clone des origins anlegen, den als neuen Remote eintragen, dann einen lokalen tracking branch erstellen, auf den wechseln, dort dann commiten und jeweils nicht vergessen diese Commits im Parent Repo dann zu bestätigen (einzeln natürlich, sonst sieht man dort die history nicht). Das geile daran: macht man dann im Parent Repo einmal git submodule update ist man natürlich wieder auf einer disconnected revision.

Yeeehaw. Give me useless extra steps!

Umbenennen ist noch so eine Sache, DVCS sind ja so toll beim Mergen, nicht? Aber wehe man benennt ein Submodule um. Dann nämlich kriegt man das nach git pull && git submodule update NICHT. Nein, viel besser man muss lediglich .git/config von hand bearbeiten um den alten submodule Eintrag zu entfernen und dann ein git submodule init && git submodule update machen.

Yeah. Give me useless extra steps!

Mein Fazit: GIT, das Tool für Leute die gerne mehr Zeit in ihr DVCS als in ihre Software stecken wollen.

Google Wave kurz erklärt

Ken Schwaber in Action

Ich muss sagen, er spricht wirklich gut - seine Erklärung von Scrum ist jedenfalls wirklich gut verständlich.

 Hier auf YouTube

Ein paar interessante Punkte zu seinem Vortrag:

  • Keine Folien - er hällt den Vortrag komplett frei
  • Kein Verkaufsgespräch - er nimmt klar in den Mund welche Probleme durch Scrum sichtbar werden (und natürlich ist das eine ganz hervorragende Verkaufstaktik)
  • Alle Graphen / Schaubilder malt er on demand an die Tafel - einfach und effektiv.

Scrum Master

Nach ausführlicher intensiver und langwieriger Schulung von zwei Tagen - bin ich jetzt zertifizierter Scrum Master.

Wow.

Da sollte man natürlich etwas darüber schreiben was Scrum ist und was ein Scrum-Master tut. Well... ich rede mich mal damit heraus dass das Training sooo anstrengend war dass ich jetzt einfach nicht mehr kann.

Aber gott sei Dank gibt es auf YouTube ein paar Berichte von anderen Leuten die Scrum machen. :-)

Neben all dem Spaß gibt es aber auch  etwas ernsthaftere  Erklärungsansätze zu Scrum.

Git - das Werkzeug für Leute die gerne viel von hand machen

Puh, ich muss mir mal den Frust von der Seele schreiben den dieses Werkzeug mir bereitet hat.

Zuerst das Setup: Ich will zu einem Open Source Projekt beitragen dass leider GIT und GITHUB verrwendet.

Zuerst mal was mich wirklich frustriert hat. ich habe an ein DVCS (und speziell eines dass so sehr hyped wird wie GIT) ein paar ganz spezifische Requirements:

  1. Ich will dass ich meine Patches sauber getrennt voneinander entwickeln kann, damit man jeweils den ganzen Patch einfach sehen kann.
  2. Ich will die History dieser Entwicklung erhalten, damit die Code-Reviews die stattgefunden haben und die Gründe für Änderungen sichtbar bleiben
  3. Ich will einen stabilen Link auf den Head nur dieser Patches, damit der Maintainer es einfach hat diese bei sich zu integrieren und ich den in BugReports angeben kann
  4. Ich will die Patches als Layer über mein repository legen, damit ich von den Bugfixes die ich bereitstelle schon etwas habe solange sie noch nicht in dem Projekt akzeptiert wurden. Dieses Overlay-Repo stelle ich möglicherweise auch anderen Leuten zur Verfügung - optimalerweise können sie da auch Commiten.
  5. Ich will wenig Arbeit damit haben, damit ich mich auf die eigentliche Entwicklung konzentrieren kann und nicht ständig mit dem DVCS kämpfen muss.

Das letzte Requirement ist für mich dabei das wichtigste. Ich will Software und Patches entwickeln - und das DVCS das mich dabei unterstützt MUSS in den Hintergrund treten - sonst ist es schlicht und ergreifend ein schlechtes Tool. Und das ist auch schon der Todesstoß für GIT. So viel kann ich schon mal verraten - eigentlich kann GIT diese Requirements (die ja wohl für ein DVCS selbstverständlich sind) nämlich gar nicht erfüllen.

Dazu kommt dann natürlich noch der Ärger den man mit dem Index hat?.

Aber mal zu den Details.

Getrennte Patch-Entwicklung: Prinzipiell gibt es wohl zwei (oder drei) möglichkeiten. Die erste und die die sowohl im Manual als auch im IRC-Channel empfohlen wird ist das man doch einfach für jeden Patch einen branch macht. Die zweite und dritte Möglichkeit ist ein tool wie  StGit oder  TopGit zu verwenden. Beides sind externe Tools, die sich überhaupt nicht in GIT integrieren - und das bereitet eine Menge Probleme. StGit hab ich intensiver getestet - und von TopGit dass sogar in GIT-Kreisen als "kompliziert" gilt werde ich daher tunlichst die Finger lassen. Das Problem ist, dass man die Verwendung der Tools nicht mischen darf. Dazu ein Beispiel: Wenn man mit Mercurial PatchQueues arbeitet (das war letztlich mein Workaround, der wenigstens funktioniert!) dann sind die patchqueue Kommandos einfach weiter Subkommandos von hg - das bedeutet auch dass sie den vollen Repository-Status kennen und ihn in die Fehlermeldungen einbeziehen können. In der Praxis bedeutet dass, das wenn ich ein hg patchqueue Kommando absende und das Repository gerade in einem status ist der dazu nicht passt - dann kriegt man eine Fehlermeldung die einem nicht nur sagt das ein Problem aufgetreten ist, sondern auch was man tun kann um es zu lösen. (Leider sind die nicht immer perfekt, aber das ist wenigstens ein Start). Häuffig passiert das wenn man nach einem update von upstream die patches wieder anwenden will aber vergessen hat vorher den aktuellen status in hg zu commiten. Oder wenn man einen Patch verändert hat und zum nächsten wechseln will ohne das vorher aufzuzeichnen etc. Bei StGit ist das anders. Wenn da der Repository-Status nicht zu dem passt was StGit denkt das er wäre, dann wird das Repository einfach zerstört.

Yeah!

Bis man das dann gecheckt hat ist das Repository in einem Zustand, dass es weniger Arbeit ist mit diff und patch die patches wieder herauszufummeln als sich durch die diversen history-rewriting operatoren zu fummeln um doch etwas hinzubekommen was hoffentlich vielleicht doch das ist was man eigentlich hätte gewollt haben sollen. Oder so ähnlich.

Dazu kommt dass StGit die Patches schlicht als normale GIT-Revisionen speichert und die history-rewriting Möglichkeiten nutzt um das PatchQueue feeling aufkommen zu lassen. Und das ist dann auch der Grund wieso man StGit und Git Kommandos NIE, NIE, NIE mischen darf.

Bleibt also nur der erste Ansatz: Für jeden Patch einen Branch anlegen. Das wirkt eigentlich auch ganz Vernünftig, denn man kriegt dadurch eine Menge: Die History wird erhalten, man hat stabile Links in jeden Patch (ist ja nur ein Branch) und natürlich getrennte Entwicklung. Leider hört es da aber auf. Man kriegt nämlich keine Hilfe dabei die Patches als Layer übereinander zu legen - und besonders wichtig - wenig Arbeit damit zu haben.

Wenn von z.B. von upstream den aktuellen stand haben möchte, muss man das einmal für jeden Branch machen - und dann dort die Konflikte lösen. Hat man Abhängigkeiten zwischen den Patches (Bugfixes die aufeinander beruhen z.B.) wird es noch abenteuerlicher. Richtig toll wird es dann wenn man die ganzen Patches als Layer über sein eigenes Repository gelegt betrachten möchte. Unter GIT wird dazu empfohlen sog. "Integration" Branches zu verwenden - also Branches die man periodisch neu anlegt (mit sog. squash-commits) die aus einem anderen Branch nur noch einen einzigen Commit auf dem "integration" Branch machen. Das ist übrigens auch der Weg wie man aus den branches schöne patches macht - im integration branch. Das geile daran: Man muss das immer wieder machen - denn jedes mal wenn man die Patches weiterentwickelt muss man auch den integration branch komplett neu anlegen.

Ach ja, oder man schreibt natürlich in der History herum - aber dass hat letztlich den gleichen effekt - man hat eine Menge Arbeit und die URLS zu diesen Commits bleiben erst nicht die gleichen.

Ach genau, und es gibt natürlich noch Leute die Sagen History Rewriting geht und ist cool also mach es doch die ganze Zeit, dann bleiben auch deine Patches sauber. (Also im Prinzip das was StGit tut nur von Hand). Damit bin ich aber wieder meine Stabilen URLs los - und dass ist für mich nicht akzeptabel, weil ich dann wieder nix habe was ich in Bugreports verlinken kann)

Große Klasse.

Jetzt nachdem ich den ganzen Ärger durch hatte bin ich dann dabei angekommen dass ich schlicht keine Möglichkeit habe dem Upstream möglichst viel Arbeit abzunehmen und gleichzeitig Commit-URLs zu haben die sich nicht verändern (ach ja, dazu kommt noch das Upstream keine Branches in GITHUB mag - ich vermute mal dass ihnen das auch zu viel Arbeit ist). Na gut, wenn sie schon GIT verwenden müssen, dann dürfen sie auch die Extra-Arbeit machen.

Darum verzichte ich jetzt darauf saubere Patches bereit zu stellen, sondern Commite einfach in mein Repository und schiebe den 'master' nach GITHUB. Damit ist der Onus eben bei Upstream das sie möglichst häufig Mergen um die Übersicht nicht zu verlieren. Super ist das natürlich nicht - und mit jedem Code-Review von einem Patch den ich bereitstelle wird das dann halt unübersichtlicher.

Was ich daran nicht verstehe: Es kann nicht sein dass ich der einzige bin der diese Probleme hat. Jeder der Open Source Entwicklung mit GIT macht muss früher oder später darauf stoßen. Also was ist los?

Rein logisch betrachtet ergeben sich daraus eigentlich nur zwei mögliche Schlüsse:

  • Entweder GIT-User sind einfach so geil auf ihr Tool, dass sie gar nicht merken wie viel Extra-Arbeit das Tool ihnen aufzwingt und sie sehen diese Komplexität einfach als notwendig statt als zufällig an.
  • Oder aber sie haben, wie ich, einfach aufgegeben saubere History, einfaches merging für Upstream und getrennte Entwicklung von getrennten Patches zu betreiben.

Ich persönlich vermute letzteres - schon alleine um nicht alle Open Source Entwickler für blöde erklären zu müssen. Damit verstehe ich dann aber die Popularität von GIT gerade in OpenSource Projekten überhaupt nicht. Hier sind doch eigentlich gerade die Leute denen eine saubere und transparente Entwicklung wichtig ist?

Hier noch ein paar Pointer für diejenigen die aus der Git-Hölle entkommen wollen:

  •  Mercurial bietet mit den  PatchQueues ein mächtiges Werkzeug an um diese Patch-Entwicklung und verfeinerung sauber gretrennt vom Repository vorzunehmen. Das schicke daran: diese Patchqueues sind Versioniert - aber vom Repository getrennt gespeichert. Dadurch lässt sich das auch ganz hervorragend über ein GIT/HG/SVN Repository drüberlegen - und man kann den ganzen Ärger mit GIT vermeiden. Dazu lassen sich diese Queues auch relativ einfach über  BitBucket teilen, so dass man auch zu mehreren direkt an patches arbeiten kann.
  •  Bazaar hat  Looms die in etwa wie hg patchqueues zu benutzen sind, aber dafür den Vorteil haben dass sie ganz regulär mit einem push an ein remote andere Repository übergeben werden können - damit ist Zusammenarbeit auch um ein Vielfaches einfacher. Und natürlich wird auch dort die Historie der Patches erhalten. (Für die Geschwindigkeits-Proleten noch ein Hinweis: Bazaar ist heute so schnell wie Git war als es erschien - wenn Git also damals für Kernel-Size-Trees geeignet war...)

Kent Becks keynote auf der Railsconf 08

Und er erzählt dabei ein paar Geschichten. Ohne einen Punkt.

Das ist ein ganz interessanter Rückblick auf seine Vergangenheit, seine Meinung und Art wie er spricht.

Das Beste ist aber die Fragerunde am Schluss - in der wird es nämlich auf einmal richtig Politisch:

How is it, that the thing that I could do could contribute the most possible. I'ts gonna take getting involved with the people whose lives are affected by the programs that I write. Whether they're dockworkers, or policemen or whoever. They have to gain power in that process.

One of the Principloes that I've used always, always, is the principle of mutual benefit

I try to finde a way where everybody can do better out of the activities that I'm involved in. I fall short of that at times, but I'm always looking for that.

And I think software as an industry falls short of that. There are winners and losers in software development. And I think thats really too bad, because I think it's mostly a choice.

And I'd love to find a way to get past that.

Schaut euch den Kontext um dieses Statement an - es lohnt sich!

 Hier gibt's den Vortrag

IDE-Killer Features: Das Outline View

Ich hab schon eine Weile nach einem Ersatz für  Textmate gesucht, da ich unbedingt beim Coden ein Outline view sehen möchte, in dem ich die Struktur einer Code-Datei wiederspiegelt. (Nicht nur ein Function Popup - das kann ja jeder, aber das ist eben nicht das gleiche.)

Well und heute hab ich einfach noch mal im TextMate Channel gefragt weil ich gerade auf der Suche war ob vielleicht in der nächsten Version von TextMate dieses Feature enthalten ist.

Und sie da: Command-Shift-T und man kriegt das Feature!

YES!

PHP

Bäh! = Ich hab mir heute mal mit einigen bekannten die doch etwas besser PHP können angeschaut wie man in die Wikipedia ein plugin einbaut.

Und boah, das ist echt superecklig.

Das geht schon damit los dass man an einen Array nicht vernünftig etwas anhängen kann. Denn, das muss man sich mal auf der Zunge zergehen lassen, arrays sind natürlich keine Objekte - dafür aber auch noch gleich dictionaries.

Und etwas anhängen an einen Array ist daher eine total schwierig. Es gibt zwar eine (globale!) Funktion - so in der art von array_push_value() oder so, aber das will niemand schrieben, desshalb gibt es dafür eine extra Syntax (!!!):

$someArray[] = "fnord";

Geil oder?

Und natürlich ist Wikipedia auch ein total gewachsenes Projekt, daher gibt es tausende von globalen Variablen die man manchmal überschreiben, manchmal anhängen und manchmal irgendwas machen muss.

Auf meine Frage wieso man so etwas so macht, fiel auch meinen Bekannten auch nur ein "das ist halt vermutlich so schneller" ein. Denn, der ganze Code muss ja für jeden Seitenabruf neu geparst werden.

Wie krass!

Und es ist nicht so das es dann für das Plugin registrieren eine Funktion gibt, in der man vielleicht noch ein Verzeichnis übergibt, wo dann nach einem standard-layout die ganzen Files drin sind. Nein! man muss x verschiedene globale variablen von hand anfassen.

*kotz*

 Wers nicht glaubt, schaut selber nach!

Cappuccino und jQuery im Vergleich

Ich beschäftige mich ja seit einiger Zeit intensiver mit Web-Entwicklung - und da im besondern mit  Cappuccino um damit GUIs in WebBrowsern zu bauen.

Cappuccino ist zwei Sachen - eine dünne Schicht JavaScript die einen Translator implementiert der aus  Objective-J (Quasi  Objective-C für JavaScript) normales JavaScript macht und eine Bibliothek an Objekten die der [Cocoa Bibliothek] von Apple aus dem Gesicht geschnitten ist.

Und Cocoa ist immer noch die schönste und knackigste Bibliothek die ich kenne - allerdings kenne ich auch noch nicht so viele.

Um so spannender fand ich es daher  eines der Beispiele des Cappucino Projektes noch einmal  in jQuery implementiert zu sehen ( Blog dazu)

 jQuery ist nämlich eine Bibliothek die die Möglichkeiten von JavaScript (Closures!) mal wirklich vollständig ausreizt und soweit ich das beurteilen kann ein Musterbeispiel von richtig gutem JavaScript Code ist.

Auf der anderen Seite ist Cappuccino - eine Sprache die von C portiert wurde, und die daher eben keine Closures einsetzt - weder in der Sprache, noch in der Bibliothek.

Und das rennen fängt gut für jQuery an - jQuery braucht für das gleiche Beispiel nur 45 Zeilen Code, während Cappuccino mit 400 Zeilen dabei ist - und enthält an manchen Stellen sogar noch mehr Bling! (Die Bilder faden schön ein statt einfach nur zu erscheinen)

Schaut man sich die Beispiele genauer an, stellt man fest, dass bei jQuery zu den 45 Zeilen Javascript noch mal 200 Zeilen CSS kommen und dass der JavaScript Code völlig ohne Leerzeilen auskommt, während bei Cappuccino besonders auf übersichtlichkeit geachtet wurde.

Korrigiert man das und vergleicht erneut, dann sieht das Ergebnis etwas anders aus: jQuery + CSS ~= 200 Zeilen vs. Cappuccino ~= 200 Zeilen.

Whoa.

Also muss der Vergleich inhaltlich stattfinden: Cappuccino isoliert den Applikationsentwickler komplett vom DOM und seinen Schwierigkeiten, während jQuery natürlich komplett damit Arbeitet - und man sich auch selber um die Komplikationen kümmern muss die man mit der Browserkompatibilität hat.

Dafür ist der Code von jQuery inhaltlich wirklich sehr schön kurz - ich finde man sieht ganz hervorragend was man erreichen kann wenn man benannte Parameter (hier durch JavaScript Objekt-Literale Vertreten) und konsequenten Einsatz von Closures kombiniert.

Das hier zum Beispiel:

$.each(data.items, function(i,item){
   img = new Image();
   img.src = item.media.m;
   img.onload = function() {
        $(this).animate({opacity: 1}, "normal");
   }
   $(img).css({opacity: 0}).appendTo("#content").wrap("<div></div>");
   if ( i == 20 ) return false;
   });

ist einfach sehr ausdrukstark. Ich freue mich schon darauf wenn Apple Snow-Leopard herausbringt und damit Closures auch in Objective-C einzug halten - weil dann wird auch Cappuccino diese Möglichkeiten endlich nutzen ohne die Kompatibilität mit Cocoa zu verlieren.

Auf der anderen Seite finde ich den Objective-J Code wie bei Cocoa auch sehr ausdrucksstark - und vielleicht etwas verbose. Dafür dokumentiert sich der Code aber auch ganz excellent.

Und da er nicht länger ist als der andere, sehe ich da überhaupt kein Problem.

Alles in allem also ein guter Grund jQuery zu lernen um die Möglichkeiten von JavaScript wirklich mal zu verstehen.

  • Posted: 2009-04-30 07:24 (Updated: 2009-04-30 07:30)
  • Author: dwt
  • Categories: software
  • Comments (0)

Ein Film über Softwareentwicklung

 Der erste überhaupt!

Insbesondere ist einer der betreuenden Professoren mein Onkel - daher hab ich den Link auch. :)

Das Konzept dass das Projekt rollend von einer Generation von Studenten an die nächsten weitergegeben wird find ich klasse. Code, Dokumentation, Bugs - alles kriegt man von den Vorgängern. Und da kommt noch mehr gutes: Kurze Iterationen 3 Wochen pro Iteration, klare review und status Meetings am ende jeder Iteration.

Soweit so gut. Einiges hat mir aber auch nicht so gut gefallen. Z.B.:

  • Ein Semester nur Planung und Einarbeitung - in dieser Zeit wird für die simulierte Firma kein Wert erzeugt den sie Verkaufen können. Das haben die Studenten auch selber gemerkt. "Die erste Phase war recht lang und damit auch sehr kostenintensiv." No shit sherlock.
  • Und natürlich lauter Spezialisten - keine Polivalente Teams
  • Die ganze Suite der Rational Tools wird eingesetzt
  •  RUP als Prozess- mit all seiner "Schönheit"

Das Projekt wird als klassischer Wasserfall umgesetzt - und das Feedback der simulierten Kunden war dann auch klar: "Es gab da einige Momente im Projekt, da hätte man schon lange gesagt: 'Ich kündige den Vertrag und wechsle die Firma'".

Man könnte also sagen die Studenten sind optimal auf das Wirtschaftsleben vorbereitet.

Aber alle Kritik zur Seite: Das ist trotzdem noch lange das beste Software-Projekt das ich bisher gesehen habe.

Jaunty Jackalope on VirtualBox 2.2.0

Well, das neue Ubuntu sieht gut aus. Viele Details gefallen mir besser als beim vorherigen.

Insbesondere kann es jetzt korrekt die MacBook Pro Tastatur erkennen und die Konfiguration der Alt-Taste als Third-Level Chooser funktioniert jetzt auch etwas logischer (wenn auch immer noch recht versteckt).

Das einzige was absolut nicht gehen wollte war die Maus-Zeiger Integration. Aber Gott sei dank habe ich nach einigem hin und  doch im Netz den entscheidenden Hinweis gefunden.

Man muss die xorg.conf mal wieder von hand anpassen...

Hrm.

Dafür geht es jetzt. 3D Integration krieg ich aber nach wie vor nicht zum laufen - während das mit Intrepid Ibex noch prima funktionierte.

Well, man kann halt nicht alles haben. :)

Javascript - the good parts

Beim Schimpfen über Javascript vergisst man immer gerne dass da doch relativ viel von Scheme drin ist.

Zum Glück gibt es Douglas Crockford - und der hat  bei Google darüber gesprochen was die guten und schlechten sachen sind.

Sehenswert wenn man mit Javascript arbeitet / arbeiten muss.

p.s. Er hat auch  JSLint geschrieben.

Ruby Videos

Während meinem Urlaub habe ich mir eine Menge Videos angesehen - so viel Zeit hat man ja sonst nicht. Allerdings nicht irgendwas. (OK, etwas  Daily Show war auch dabei :)

Diese Videos haben mir besonders gut gefallen:

  •  Jive Talkin: DSL Design and Construction From a creator of many DSLs a short overview over the specific techniques and how he goes about doing them. (Test driven of course)
  •  Improving the usuability of your Ruby on Rails application A nice talk about website usability and very specific things that you can do to enhance it (with a great example)
  •  Tourbus A really nice talk about how to optimize ruby on rails applications (but really it's more general and can be used for anything). He especially talks about how you can easily get one to two orders of magnitude speed improvements on the first optimization pass of an app.
  •  BDD with Cucumber A talk about how Behaviour Driven Development works in practice and how it can be used to drive development - from a guy at Thoughtworks who gives very practical examples.
  •  La Dolce Vita Rubyista A talk about how agile development should be - shown in a series of short movies which are quite funny.
  •  Testing as Communication How Programmer Testing can be used to achieve better communication with your customers.
  •  Aristotle and the art of software development A talk about three major currents of philossophy - and how they may relate to software development and which programming language to choose.
  •  Using Metrics to take a look at your code Talk about possible code metrics and how to use them to discover and keep an eye on bad parts of your code.
  •  Effective and creative coding Talk of a psychologist about directed attention and how to recharge it to be a more effective and creative coder
  •  The Grand Unified Theory... ... of Programming. In this talk, Jim Weirich talks about Connescance as a guide to how to determine what is good and what isn't good programming.

Und auf diese Tools bin ich dabei noch mal gestoßen - dabei sind wirklich ein paar sachen die extra cool sind:

Core War

Ich hab mich schon länger mit dem Gedanken herumgetragen dass es eigentlich mal einen schönen aktuellen  CoreWar clienten für den Mac geben müsste.

Und, irgendwie kam es bisher nicht dazu - aus irgend einem Grund hat niemand einen geschrieben.

Well, jetzt hab ich mal einen minimalen Anfang gemacht um herauszufinden wie man so etwas überhaupt programmieren müsste.

Hier ist das vorläufige Ergebnis.

WARNING: Work In Progress!

Das ist natürlich völlig unfertig - Es läuft genau nur ein Krieger ( IMP) - und der auch nur weil er alleine ist. :-)

Aber, ich habe eine Abstraktion für die VM, ein View was das Ergebnis anzeigt, und ein paar Tests die auf der VM herumrödeln und schauen dass sie prinzipiell das richtige tut.

Kleinigkeiten die noch fehlen wären zum Beispiel ein Parser für Redcode, Einstellungen um die Applikation an die verschiedenen Regelwerke anpassen zu können und natürlich eine Implementierung aller Redcode Instruktionen...

Also ein Anfang. Und man sieht schon etwas. :)

Ach ja, hier noch was für  echte Core War fans...

Rollen im Software-Bauen

Der Podcast "Software Engineering Radio" hatte zwei sehr gute Folgen  Roles in Software Engineering ( fortsetzung). Der Anfang ist zwar etwas langsam, aber dann wird es sehr schnell hochinteressant wenn die Rollen und deren Mindset gegeneinander Abgrenzt werden.

Vor allem das Mindset als definierender Punkt hatte ich so klar bisher noch nirgends gelesen. Schade nur dass es genau diese Sammlung an Mindsets nicht dort als Text gibt.

Mal schauen - das war so gut, dass ich es mir eigentlich mal aufschreiben möchte.

Der sechste Sinn

Wäre es nicht cool wenn man beliebige Metadaten zu irgend etwas an beliebigen Stellen abrufen könnte?

Am MIT Media Lab haben sie dazu einen Demonstrator gebaut - eine Webcam, plus einen kleinen Rechner plus einen batteriegetriebenen Mini-Beamer - und das alles zum umhängen.

Damit kann man dann zum Beispiel beim Einkaufen zu einem Produkt abrufen ob es ökologisch hergestellt wurde, wie das Produkt bei Amazon bewertet wird, wie sich eine Geschichte weiter entwickelt hat die man gerade in der Zeitung ließt, ob und wie viel sich ein Flug verspätet hat für den man gerade sein Ticket anschaut... Die Möglichkeiten sind unbegrenzt.

Das coole daran ist dass der Apparat letztlich auf Gesten reagiert und auf jede Oberfläche projizieren kann. Also zum Beispiel eine Tastatur auf die eigene Hand - für einen Taschenrechner, oder eine Telefontastatur, oder es kann erkennen wenn man eine "Photo-Geste" macht und kann ein Photo machen von dem was man gerade sieht.

Pretty neat he?

 Hier gibts ein Demo-Video auf der TED-Conference

(Danke an Joachim für den Hinweis)

Cappucino != Cocoa

Tja, also nach längerer Neugierde habe ich mich mal mit  Cappucino auseinander gesetzt und ein wenig damit Programmiert.

Und das hat für mich als Cocoa Programmierer eine Menge Spaß gemacht.

Erst mal ein paar Kleinigkeiten:

  • Der Java-Script Parser von Safari saugt. Er sagt einem nie wo der Fehler jetzt genau aufgetreten ist. :-( Unbedingt mit Firefox und Firebug entwickeln!
  • Wenn man sich den git tip of the tree auscheckt kriegt man weit mehr Klassen als in der offiziellen Dokumentation erwähnt sind. Insbesondere funktioniert das nib2cib tool auch ein wenig besser - und das spart unmengen von Zeit.
    • Allerdings funktioniert nib2cib auch nicht soo gut. Viele Klassen die es können könnte gehen damit nicht. NSScrollView zum Beispiel.
  • Wenn man sein eigenes Objective-J kompilieren will darf man keine spaces im Pfad haben. (arrrrghhh!!!!!)
  • Man kann (noch) nicht den Code so ohne weiteres in Unterverzeichnisse auslagern. Das macht die Projekte unübersichtlich - aber angeblich soll das bald gefixt sein.
  • nib2cib darf man nie mit mehr als einem Filenamen aufrufen. Sonst schreibt es nämlich einfach in das zweite Argument den output hinein.
    • Wo ich gerade darüber nachdenke: das geht eigentlich mit kaum einem objective-j tool ojtest zum beispiel... Dabei ist der Startup von Rhino immer das langsamste daran. :-(
  • Und man muss einiges an Umgebungsvariablen setzen. Am besten macht man sich ein ein shell script was diese dinger setzt und dann wieder eine shell exec'd. Damit hat man dann gleich eine Arbeitsumgebung für Cappucino ohne alles irgendwohin in standard-Betriebsystem-Locations installieren zu müssen.
#!/bin/sh

PROJECT_DIR="/path/to/the/cappucino/sources/but/without/spaces/cappuccino"

# you can move this elsewhere to keep things separate
export STEAM_BUILD="${PROJECT_DIR}/build"
TOOLS_DIR="${STEAM_BUILD}/Cappuccino/Tools/objj"
NIBTOOLS_DIR="${PROJECT_DIR}/Tools/objj"

export OBJJ_HOME="${TOOLS_DIR}"
export PATH="${PATH}:${TOOLS_DIR}/bin:${NIBTOOLS_DIR}/bin"
"${SHELL}"

Damit kann man immerhin die ganzen objj tools (ojtest, nib2cib, etc) direkt benutzen.

Cappucino selber benutzt sich tatsächlich ziemlich wie eine recht alte Version von Cocoa. Erstmal keine Bindings und entsprechende Controller und !CPBundle ist reichlich underpowered - Lokalisierter Resourcen-Lookup ist damit erst mal noch nicht drin.

Die Tools sind natürlich nicht so toll. Insebesondere fehlt ein vernünftiger Ersatz für Interface Builder.

Aber ansonsten rockt  Cappuccino schon gewaltig. Jedem Cocoa-Programmierer sei also eine Beschäftigung damit schwer ans Herz gelegt.

Xcode mit svn 1.5

Eigentlich dachte ich ja ich hätte das schon gebloggt - aber ich habs nicht wiedergefunden. (Vielleicht sollte ich nochmal mit google suchen?)

Ah well.

Dieses Script bringt Xcode mit svn 1.5 via  Fink installiert zum laufen.

#!/bin/sh

svn_libs=/sw/lib/svn15

cd /Developer/Library/Xcode/Plug-ins/XcodeSubversionPlugin.xcplugin/Contents/MacOS || exit 1
ditto XcodeSubversionPlugin XcodeSubversionPlugin.new

libs=`otool -L XcodeSubversionPlugin.new | grep libsvn | awk '{ print $1 }'`
 
for lib in $libs ; do
  new_lib=`echo $lib | sed "s,/usr/lib,$svn_libs,g"`
  echo "install_name_tool -change $lib $new_lib XcodeSubversionPlugin.new"
  install_name_tool -change $lib $new_lib XcodeSubversionPlugin.new
done

install_name_tool -change /usr/lib/libapr-1.0.dylib /sw/lib/libapr.0.dylib XcodeSubversionPlugin.new
install_name_tool -change /usr/lib/libaprutil-1.0.dylib /sw/lib/libaprutil.0.dylib XcodeSubversionPlugin.new

echo otool -L XcodeSubversionPlugin.new
otool -L XcodeSubversionPlugin.new

echo
otool -L XcodeSubversionPlugin.new | grep svn | awk '{ print $1 }' | xargs -n 1 ls -la

exit 0

Ach ja, am Schluss muss man noch von Hand in /Developer/Library/Xcode/Plug-ins/XcodeSubversionPlugin.xcplugin/Contents/MacOS das original zur Seite bewegen und bei dem neuen das ".new" streichen.

Endlich @ und € in Ubuntu

Schon länger betreibe ich ein  Ubuntu in  VirtualBox - einfach weil es geht und man es dann doch irgendwann braucht wenn man keine Zeit hat es einzurichten.

Und das ist geil.

Die Geschwindigkeit ist ok (man muss nur die Guest-Aditions installieren) und im Nahtlosen Modus kann man die Ubuntu Fenster einfach eingebettet in den normalen Desktop benutzen

Nice. Wenn da nicht der ärger mit @ und € wäre - ausgerechnet die gehen nämlich per default nicht.

Fear no more, ich hab es hingekriegt. (Ubuntu Gnome Default Desktop 8.11)

  • Menü System -> Einstellungen -> Tastatur
  • Zweiter Reiter ("Belegungen")
  • Tastatur: Apple, Apple (oben wie unten, das korrekte "MacBook/MacBook Pro (intl)" ließ sich nicht auswählen)
  • Belegung "Germany Macintosh" war schon ausgewählt
  • Weiter gehts bei "Other Options" darunter
  • In dem Fenster was dann aufgeht dann "Third level choosers" aufklappen und
  • "Press any of Alt keys to choose 3rd level" auswählen

Yay!

Jetzt muss ich nur noch herausfinden wie man Controll und Command austauscht, damit die Tastatur Shortcuts vernünftig funktionieren...

 via

OD Completion Dictionary works with Xcode 3

Hrm, das ist mir doch ganz entgangen bisher.

Aber:  here it is!

Was es tut: Beliebige Textbausteine in Xcode schnell einsetzen. Das geht zwar auch ohne ODCompletionDictionary, aber, mit kann man es auch in Xcode live bearbeiten. Und das macht das Feature eigentlich erst richtig nützlich.

Landing on Mars (with Squeak)

I just started playing around with  Mars which is a bridge from Squeak to Cocoa, which allows Squeak Programms to have a Cocoa GUI.

Pretty nice - however not quite as easy to get installed if you are a SmallTalk newbie like me.

 There are installation instructions on the Mars homepage however I couldn't quite follow them, so I enhanced them a little and give you the rundown here:

Instructions

  • I downloaded the basic Image from  http://ftp.squeak.org/3.10/Squeak3.10.2-7179-basic.zip
  • Got the Virtual Machine from  ftp://ftp.smalltalkconsulting.com/experimental//Squeak%203.8.21beta1U.app.zip
  • Installed basic developer tools by executing <HTTPSocket httpFileIn: 'installer.pbwiki.com/f/LPF.st'.> in a workspace window (select it and hit command-d)
  • Then I ran
    Installer universe 
    	addPackage: 'OmniBrowser';
    	addPackage: 'OmniBrowser-Morphic';
    	addPackage: 'OmniBrowser-Standard';
        	addPackage: 'OmniBrowser-Refactory';
    	install.
    
    to get the basics and
  • installed Mars by executing
    Installer wiresong project: 'ob'; install: 'OB-Monticello'.
    Installer lukas project: 'omnibrowser'; install: 'OB-Tools'.
    
    Installer ss project: 'Mars';
    	install: 'Mars';
    	install: 'OB-Mars'.
    

After that OBMarsWorld execute. replaces the menubar of Squeak with the Cocoa stuff.

:) Have fun!

Oh, and by the way, I just tried this with the dev image available from Damien Cassou at  http://damiencassou.seasidehosting.st/Smalltalk/squeak-dev

This image already has most stuff preloaded, so you can just run

Installer wiresong project: 'ob'; install: 'OB-Monticello'.
Installer lukas project: 'omnibrowser'; install: 'OB-Tools'.

Installer ss project: 'Mars';
	install: 'Mars';
	install: 'OB-Mars'.

to get Mars installed and then start it by running: OBMarsWorld execute.

Wenn Apple mail auf einmal keine Passwörter mehr speichert...

... im Schlüsselbund, dann möglicherweise deswegen weil man gerade  Services Scrubber verwendet hat um sein Services-Menü aufzäumen.

Und das funktioniert indem es die Info.plist eines Programms manipuliert.

Doh. Wenn das nämlich eine signierte Applikation ist (wie alle Apple-Programme) dann stimmt danach natürlich die Signatur nicht mehr. Und das bedeutet dass sie nicht mehr auf den Schlüsselbund zugreifen können.

Natürlich ohne sich irgendwo in logfiles zu beschweren.

:-/

hg, bzr und git als svn superclient

Ein langer Traum ist in Erfüllung gegangen - alle Versionskontrollsysteme ( hg,  bzr,  git und natürlich  svn) unterstützen endlich das Reden mit einem Subversion-Server.

Das bedeutet, man kann jetzt SVN als Lingua Franca mit allen verteilten Versionskontrollsystemen einsetzen um einen gemeinsamen Server zu haben von dem alle pullen und pushen können. Oder kurz gesagt: Wenn man SVN als Server hat, kann jeder benutzen was ihm persönlich am meisten liegt.

Das funktioniert natürlich noch alles nicht perfekt - aber es fängt an.

Und daher hab ich mal aus Spaß ein Projekt mit jedem der VCS ausgecheckt und bin etwas überrascht von den Ergebnissen:

  • bzr git und svn haben den root des Projekts einfach als große Ordner-Hierarchie ausgecheckt, so wie das in svn eben abgebildet ist.
  • hg hat als einziges ohne Zusatz-Optionen erkannt das es trunk, branches und tags gibt und das auf die entsprechenden nativen Konzepte (branches) abgebildet. (Das müsste mit mehr Aufwand aber mit bzr und git auch gehen).
  • Der Import hat schon mal recht unterschiedlich lange gedauert:
    • bzr: 20 min
    • git: 14 min
    • svn: 7 min
    • hg: 7 min (sogar drei Sekunden schneller als svn! :)
  • Logischerweise sind damit die Repositories auch völlig unterschiedlich groß:
    • bzr: 83 MB
    • git: 93 MB
    • svn: 162 MB (Zweimal die Größe des ganze Source-Codes aller tags und branches, also wie erwartet)
    • hg: 5.2 MB (überraschend - angeblich steckt da die ganze History drin - so richtig glauben kann ich das aber noch nicht. Vom Platz her ist das etwa das doppelte den alleine der trunk als checkout braucht)

Hier die Kommandos die ich abgeschickt habe (mit den Laufzeit Ergebnissen)

bzr clone  http://python-nose.googlecode.com/svn nose-bzr
177,62s user 27,00s system 16% cpu 20:17,34 total
git svn clone  http://python-nose.googlecode.com/svn nose-git
57,63s user 130,80s system 22% cpu 14:02,33 total
svn co  http://python-nose.googlecode.com/svn nose
9,13s user 19,77s system 6% cpu 6:58,31 total
hg svnclone  http://python-nose.googlecode.com/svn nose-hg
27,15s user 12,25s system 9% cpu 6:57,76 total

So viel kann man daraus natürlich nicht schließen - aber mir gefällt dass man jetzt mit allen VCS an Subversion herankommt und der Weg auf dem hgsubversion ist scheint mir schon mal sehr gut zu sein. :)

The Git Index considered harmful

Endlich hab ich mal eine  ordentliche Quelle gefunden wofür  der Index bei  GIT gut ist.

Kurz erklärt: Der Index ist eine Vorstufe für jeden Commit. Man comittet zuerst in den index mit git add some_file und comitted dann den index ins repository mit git commit. Es sei denn man sagt git commit some_file in dem fall wird es direkt comitted, oder man wählt eines der anderen kommandos die irgend etwas merkwürdiges mit dem index anstellen, dann weiß man in der Regel gar nicht mehr was Sache ist.

Das hab ich nie verstanden - denn wieso noch mal eine Stufe mehr, wenn man doch sowieso lokal arbeitet und alles was man verbockt hat wieder verändern kann bevor man es pusht?

Ah well. Es gibt offenbar drei Hauptgründe:

  1. Der Index hilft besser mit einer dirty workspace zu leben
  2. Der Index hilft noch mehr über einen commit nachzudenken und ihn zu verfeinern bevor man ihn macht
  3. Linux Torvalds hat den Index erfunden und will ihn behalten

Zu 1. Eine Dirty Workspace ist manchmal praktisch

Die Idee ist dass es Änderungen gibt die jeder in seinem lokalen Checkout hat aber niemand einchecken will. Z.B. die debug-flags, oder der andere Pfad in einem makefile. Es ist viel komfortabler jedes mal zu sagen was man committen will, als jedes mal daran zu denken was man nicht committen will. Ganz davon abgesehen dass man irgendwan nicht daran denkt das man etwas nicht machen wollte. Been there, done that.

Dieses Problem hab ich auch ab und an. Zum Beispiel dieses komische File dass einen Build-Counter für den Build-Bot enthält. Eigentlich sollte das gar nicht in das repository. Aber dann war es doch drinnen. Und es nervte eigentlich nur, weil jeder lokale compile es erhöht hat. Und wenn es dann doch mal jemand comitted hat, gab es für jeden anderen natürlich einen konflikt. Sehr nervig. Oder der Debug-Flag, den man irgendwo tief in einem Framework einschalten musste. Den will ich natürlich auch nicht in einem Release haben.

Ich finde allerdings dass der Index überhaupt keine gute Lösung für derartige Probleme ist. Wenn ich lokale changes habe die ich nicht committen will, dann würde ich die viel lieber als "ignore" markieren, als jedes mal alles andere zu committen.

Ein bekannter formulierte das mal so, dass er oft code hat der den Code Testet den er comittet - und dass er den nicht im Repository haben will. Diese Variante des Arguments finde ich allerdings noch schrecklicher, weil ich in jedem Fall den Testcode auch im Repository haben will. Gerade. Damit ich später regressionstests durchführen kann. Automatisiert natürlich. Alleine der Gedanke dass der Testcode gleich wieder weggeworfen wird... *schauder*

Zu 2. Erst noch mal drüber nachdenken ist eine gute Idee

Das finde ich ein wesentlich besseres Argument: Man soll sich über einen Commit Gedanken machen bevor man ihn tut. Und damit man das tut soll man genau auswählen was in ihn hinein kommt.

Commendable.

Allerdings nur wenn man nicht richtig darüber nachdenkt. Denn git ist ja ein distributed VCS. Das heißt, alle commits sind erst einmal lokal. Und kommandos die den letzten commit einfach rückgängig machen oder noch mal neu gibt es jede menge. Sogar um mehrere History-Schritte zurück zu kommen. (Und die braucht es sowieso, denn selbst mit Index macht man immer wieder Fehler.)

Oops.

Also bleibt übrig: der Index ist ein zusätzlicher Abstraktionsschritt der keinen Wert hinzufügt, sondern nur kompliziertere Bedienung erzeugt.

Hm. Das heißt natürlich frei nach Occam, dass man den Index als überflüssiges Konzept 'über die klinge springen lassen' sollte.

Zu 3. Linus hats erfunden und will es behalten

Dass scheint mir der eigentliche Grund zu sein. Wie Torvalds es selber schon gesagt hat:  I have an ego the size of a small planet. Und daher wird es den Index auch weiter geben. Auch wenn es eine schlechte Idee ist. Und die git-Benutzer werden sich damit arrangieren, da niemand die Lust hat das wirklich auszufechten.

Zumindest ist das meine Einschätzung.

Schade eigentlich.

Hier mein Vorschlag: Für alle Index-Liebhaber gibt es eine Option in ihrer .gitrc mit der sie den Index und wie er heute ist aktivieren können. Für alle anderen gibt es den vernünftigen default wert, der den Index einfach wie bei allen anderen Versionskontrollsystemen versteckt. Das macht man am besten so, dass bei einem Update, die .gitrc so verändert wird, dass alle die git updaten den index behalten und alle die git neu einrichten den index explizit aktivieren müssen. Dass sollte am wenigsten Geschrei erzeugen.

Kommentare bitte per mail an spamfaenger ät gmx.de

Update: Es gibt noch viel mehr leute die mit der Git UI probleme haben. :)

Epson All in One

 Schickes Gerät. Vor allem ist  der Support von Epson auch gar nicht so schlecht. Per Chat wurde mir da doch sehr schnell geholfen die Scan-Funktion so umzubiegen, dass sie auch über den Print-Server und damit über das Netzwerk funktioniert.

Da hatte sich meine Hartnäckigkeit doch gelohnt - denn laut Manual geht das nämlich nicht.

Apropos Manual... Das ist so mit DRM vollgesaut, dass man daraus nicht mal ein Stück Text herauskopieren kann (nicht mal für ein Zitat!).

Zum Kotzen.

Und an sich darf man es auch nicht speichern, kopieren, archivieren... unglaublich.

Das Gerät gefällt mir ja ganz gut - aber die Software ist unter jeder Kanone. Ach ja, neben den Manuals die ja noch nicht mal alle Features enthalten.

World of Goo

Was soll ich sagen - ich bin begeistert.

 Das Spiel ist eine Mischung aus Cracy-Machines und Lemmings und macht gerade ob des total einfachen Spielprinzips unheimlich Spaß.

Aufmerksam bin ich darauf geworden, weil die Entwickler Ron Carmel und Kyle Gabler sich entschieden haben  in ihr Spiel keinerlei Kopierschutz einzubauen.

Da musste ich es doch gleich ausprobieren - und hab es mir gerade gekauft. Absolut das Geld wert. ( 15 €)

Meine Empfehlung für Weihnachten. (Mac und Windows, Linux ist gerade noch in der Entwicklung)

Liblingsutilities: Mehrere Zwischenablagen

Das ist ein eher unbekanntes Utility das mir aber unheimlich Zeit spart:  PTHPasteboard.

Unglaublich gut. Schnell und einfach so viele Zwischenablagen wie man will - die auch über Neustarts gesichert werden.

Und das ganze für umsonst - wo alle anderen Clipboard-Applikationen (und davon gibt's viele) Geld kosten.

Man kann natürlich auch für PTH-Pasteboard Geld bezahlen - aber nur wenn man noch fortgeschrittenere Features braucht.

Unheimlich nützlich - sofort installieren und einen Tag bewust ausprobieren - schon kommt man nicht mehr ohne aus.

The first and second rule of optimization are

(according to  Michael A Jackson)

  • The First Rule of Program Optimization: Don't do it.
  • The Second Rule of Program Optimization – For experts only: Don't do it yet.

Bisher dachte ich immer dass es sich dabei nur um eine andere Formulierung des guten alten: "First make it work, then make it fast" handelt.

Bis es mir jetzt wie Schuppen von den Augen fiel, dass da noch viel mehr dahinter steckt. Denn natürlich lässt sich der Spruch auch auf das tatsächliche Optimieren selber anwenden.

Wie macht man etwas schneller? Am besten in dem man es nicht tut.

Und wenn das nicht geht: Mach es zu einer anderen Zeit!

Doh.

Erstes Cocoa Heads Berlin Meeting

So, gegründet ist sie also die  CocoaHeads Chapter Berlin. Und Lustig wars auch - immerhin doch 15 Cocoa-Programmierer, die meisten davon überraschenderweise fürs iPhone. Und auch eine Menge Leute die mann schon kennt.

Der Entwickler von  Aurora,  AppFresh und  Fahrinfo Berlin war da (der überraschenderweise in Potsdam immer noch studiert!), der Entwickler von  GarageSale, einige Leute aus der iPhone-Abteilung von  Neofonie und natürlich  der Gründer und noch einige  Freelancer und andere Gesellen bei denen ich mich nicht mehr an die Applikationen erinnern kann.

Also ein ganz hervorragender Start für ein Kakaokopftreffen. :)

FoneLink 2.0

Yay!

Nachdem wir das Innenleben der Software fast komplett ausgetauscht haben ist  endlich die Version 2.0 fertig geworden.

Was ein Akt.

Von dem was die Software ausmacht, ist wirklich kein Stein mehr so gelassen worden wie er war.

Jede operation wurde Asyncron gemacht, alles in ein Konzept von Aktionen gepresst (und das war manchmal nicht einfach) die gescheduled werden und (wenn es das Telefon erlaubt) sogar parallel ausgeführt werden können.

Mein Hauptteil daran war das Datenmodell das den synchronen Zugriff auf das Dateisystem des Handies erlaubt - intern aber alle Operationen Asynchron abarbeitet.

Was gar nicht so einfach zu verkapseln war. (Dementsprechend sind die Unit Tests auch fast die noch mal halb so viel Code wie der eigentliche Code).

Das Design für das ich mich letztendlich entschieden habe ist recht simpel: Jeder Dateisystem-Knoten kann einen von mehreren Zuständen haben:

  1. Out Of Date -> Der Zustand muss mit dem Handy abgeglichen werden
  2. "Up To Date" -> nichts zu tun, die aktuellen Daten sind da
  3. Update In Progress-> Die Daten werden gerade Aktualisiert oder ein anderer Job (Meist mit Progress-Anzeige) läuft mit Bezug auf diesen Knoten.

Jobs können zum Beispiel das Kopieren auf oder von dem Handy sein.

Dazu kommt dann natürlich noch etwas Intelligenz die diese Jobs automatisch anwirft wenn es Sinn macht (Verzeichnisse Aktualisieren wenn die GUI sie anzeigt) und unnötiges Kopieren vermeidet (Es gibt einen Cache auf der Festplatte - wird eine Datei einmal vom Handy Kopiert und dann nicht mehr Verändert wird die Kopierte ab da für Operationen verwendet.) Und nicht zu vergessen: Versionierte Backup und Restores gibt es natürlich auch noch.

Ach ja und Rasend Schnell sollte das natürlich auch sein.

War nicht leicht - aber jetzt läuft es rock-solid. Und über die Implementierung erzähle ich später mal mehr.

Wuala vs. Tahoe

 Wuala und  Tahoe sind zwei technisch ähnliche Systeme mit dem gleichen Ziel: Sicher Online Dateien tauschen und speichern können.

Und das Verteilt, Verschlüsselt, Dateisystemsemantik. Als Modell haben sich beide ein Verschlüsselungs und Rechtesystem ausgedacht die ein Friendt-to-Friend Netzwerk möglich machen - also ein Netzwerk in dem man alles einstellen kann was man möchte, aber mit der Sicherheit, das nur derjenige dem man das erlaubt hat die Daten sehen kann.

Naja, eigentlich ein etwas unfaierer Vergleich.

Denn, hinter Wuala steht ein Startup, eine Firma also die jede Menge Geld in den Aufbau des Netzwerkes steckt (Interessanterweise handelt es sich dabei um eine  Ausgründung aus der ETH Zürich. Das erlaubt es dem Netzwerk jedem Benutzer erst einmal 1 Gigabyte Speicherplatz zu schenken (und ein weiteres für jeden Benutzer den man wirbt) und eben auch mittels zentraler Server, die Benutzung das Projekt vor allem am Anfang enorm zu beschleunigen und damit eine bessere User Experience zu bieten.

Auf der anderen Seite ist  Tahoe ein reinrassiges Open Source Projekt.  Buildserver,  Repositories ( Darcs), Trac... alles da.

Dafür ist das Programm noch deutlich unfertig. Immerhin gibt es am Anfang einen schönen Login Dialog - aber das war es auch erstmal.

Ah well, die Entwickler im IRC-Kanal #tahoe sind jedenfalls sehr hilfreich und nett - und der größte Teil des Projekts ist in Python geschrieben. Das ist doch schon mal was.

:-)

HG, BZR und GIT

(zu  Hotaka)

Well, am WE hab ich mich mit  Felix gerade über Versionskontrollsysteme und unsere Experimente mit  HG unterhalten, als mich jemand 'von der Seite angemacht' hat, dass doch wohl im Moment alle Welt weg von HG und hin zu  GIT wechseln würde.

Well, das konnte ich so nicht glauben, aber ich wollte mir die verschiedenen Tools dann doch mal anschauen - vor allem in Hinsicht auf  SVN Kompatibilität - denn ich setze SVN sowohl für meine  Arbeit, also auch für mich Privat ein.

Na, denn ma auf zu dem Vergleich:

GIT

... hab ich mir als erstes dran genommen, und bin erst mal dran gescheitert, das das perl-script, dass den SVN-Modus macht via Fink natürlich nicht mit meiner Installation zusammenwollte, weil diese alten Perlhacker natürlich alle davon ausgehen, das Perl in /usr/bin/perl liegt. Well, tut es bei mir nicht, bzw, in /usr/bin liegt eine alte version von Perl, die eine bestimmte Library nicht enthält, die aber das Skript benötigt. ARGH! Also erst mal einen Patch zusammengebaut und an den Maintainer geschickt der das auf /usr/bin/env perl ändert. Oh well.

Danach war aber eigentlich alles dandy, bis auf die Tatsache, das ich trotz längerem nachlesen ums verrecken nicht verstanden habe, welchen Sinn diese komische Staging-Area "Index" haben soll, die man bei GIT immer zuerst mal auffüllen muss, bevor man sie Comitten kann.

Well, GIT is powerfull - aber für meinen Geschmack zu sehr an den Geschmack von Herrn Torvalds angepasst. Mag ja sein das er nur mit inkonsistenten und komplizierten Kommandozeilenoptionen effizient arbeiten kann. Ich jedenfalls hab was besseres verdient. Ausserdem erzeugt es bei mir Ablehnung wenn Herr Torvalds aus seiner Göttlichen Eingebung sämtliches anderes für Mist erklärt und dann etwas neues macht was deutlich komplizierter ist als die anderen - ohne das klar wird, wieso diese Komplexität der richtige Default ist und man nicht das Einfache zum Default machen kann, um das komplizierte als Option anzubieten.

Fazit: Funktioniert, push und pull zum SVN server waren kein Problem und das ist schon mal ein starkes Stück. Beindruckendes Tool, dass aber auch viel Ablehnung in mir erzeugt.

 BZR

... war dann der zweite Kandidat, der nicht mehr viel Langsamer daherkommt als die anderen beiden (allerdings auch nicht zacko schnell). Allerdings, gibt es eine nette Extension die das Kommando shell hinzufügt. Das ist nett, denn dann hat man eine native Shell in bzr und hat superschnelle reaktionen, Tabvervollständigung überall, etc.

Der Checkout aus SVN hat auch prima geklappt (die Anfangsschwierigkeiten hatte ich vor einem halben Jahr, als ich mir die SVN-Python-Bindings selber bauen musste. ARGH war das ein Kampf.) Jetzt hatte ich sie aber schon und mir auch schon die notwendigen Wrapper-Skripte gebaut die die Library dann halt noch dazuladen.

Well, was soll ich sagen: pull vom SVN war hervorragend, lokales arbeiten auch, aber das Push.. das stirbt immer mit Fehler 175008 (ernsthaft!) und wirft mir dann noch an den Kopf das irgend eine property nicht angewendet werden konnte. Wenn er wenigstens sagen würde welche Property das Problem ist.. Aber naja.

Fazit: Sehr poliert. Gerade im Vergleich zu meinem letzten Test ist die Dokumentation viel besser geworden, das ganze Tool wirkt durchdacht. Vor allem der Output der Kommandos hat mir gefallen, schön aufgeräumt und übersichtlich. Dann ist da natürlich die Tatsache das dieses Tool doch immer noch das einzige ist, das tatsächlich Verzeichnisse auch Versionieren kann und mit renames vernünftig umgeht. Ahh.... Endlich ohne scheu refaktorn. :-)

HG

... will ich eigentlich schon länger mal benutzen, aber es hat mir bisher immer nur zu ein paar kleinen Experimenten gereicht. Allerdings: Felix hat sich schon anstecken lassen und verwendet das jetzt nahezu ausschließlich.

Well, mein Testcase hat leider gar nicht Funktioniert. Einigen  Anmerkungen hatte ich entnommen das HG jetzt auch auf SVN zurückschreiben kann herausgefunden wie das geht, hab ich aber leider nicht. Oh well.

Fazit: Schnell, gute Bedienung und Python - aber ungeeignet um damit gegen SVN Repositories zu Arbeiten.

Fazit Fazit

So, dann bleibt mir also die Wahl: entweder GIT zu akzeptieren um damit gegen SVN zu arbeiten, oder aber den Bug in BZR zu finden um dann damit zu Arbeiten.

Vom Bauchgefühl her würde ich mich eigentlich lieber an BZR heranmachen. Mögen tue ich HG am liebsten, das hat einfach das einfachste Design und auch noch eine sehr gute Integration in das System - so öffnet es zum Beispiel standardmäßig gleich das System Merge-Tool (opendiff) anstatt CVS like Konflitkmarker in der Datei zu verstreuen.

So macht man dass.

BZR ist auf jeden fall mein zweiter Favorit - auch Python (kann ich also Hacken) und schön durchdacht - wenn auch manchmal etwas verbose zu bedienen (pull z.B. macht kein merge, aber er sagt einem dann das man statt pull merge machen müsste. ???)

GIT wirkt wie eine mächtige Kanone - ja man kann damit auch auf Spatzen schießen - ja danach wären sie tot - aber muss man sich das wirklich antun, das jeder normale Usecase ein wenig Komplizierter zu handhaben ist als mit den anderen Tools, nur damit man im zweifelsfall auch den Linux-Kernel mit dem gleichen Tool Maintainen kann?

Ich jedenfalls beantworte diese Frage für mich mit einem klaren nein. Und werde mich jetzt erstmal auf bzr und hg werfen.

Kleine Graphik-Schmankerl

Ich habe mich über die letzten zwei Tage erneut  von Katrin inspirieren lassen.

Herausgekommen ist ein kleines Cocoa-Programm Download (Source) dass ein wenig mit solchen Grid-Animierten Ansätzen herumspielt und nebenbei noch ein wenig Sheets und Preferences verwendet.

Interessant ist dabei für mich der unterschiedliche Ansatz: Katrin war wichtig, das jeder Display Vorgang in konstanter Zeit abläuft und sie verwendet daher eine Liste der einzelnen Rechtecke. Ich hatte mir das auch überlegt, mich dann aber dagegen entschieden weil es komplexer zu Programmieren gewesen wäre.

Geschwindigkeit hat sich dann im Test überhaupt nicht als Problem herausgestellt - aber das grundsätzliche Problem bleibt. War es vernünftig den Code erst einmal einfach zu halten? Ich bin überzeugt das ja.

Ganz zufrieden bin ich aber noch nicht, weil das einzige Objekt ein View und gleichzeitig der Controller für die Preferences des Programms ist.

Aber - das Programm ist so auch kurz und Übersichtlich.

Hm.

Mal schauen was ich noch daraus mache. Vorschläge für interessante und auf dem modell ausdrückbare Algorithmen immer gerne an mich.

Hier noch ein paar Screenshots:

Screenshot Brownian Motion Algorithmus

Screenshot Random Cycle and Prefs

Fone2Phone

Fone2Phone in Action My first complete piece of work for  Nova Media. I did this after working there for about a month.

 Fone2Phone allows you to have a one stop solution to transferring everything from your cell phone to your macintosh. From there on you can either put it on your iPhone or iPod (Touch), just use it on your System or sync it to a different cell phone.

As far as the technology is concerned Fone2Phone is a subset of our more capable application  FoneLink which allows you to do all this and more. Check it out!

Skewed Lines Screen-saver

Screenshot of the SkewedLines Screensaver Just two days ago I watched the episode  Wie man sich täuschen kann of  Quarks und Co. (Which has a very nice  Video Podcast - by the way)

They had this beautiful illusion - but in an animated form, which I have never seen before.

Well, after two hours, I had a screen-saver running and really like the results.

So, here you go too. :)

Wie man eine schöne Animation macht...

Das ist nämlich gar nicht so einfach.

Ich arbeite ja nun seit ein paar Monaten bei  Novamedia - und mein erstes Projekt war, (mit einem 'sportlichen' Zeitplan von etwa 6 Wochen) bis zur  Macworld im Januar 08 das Produkt Fone2Phone fertigzustellen.

Ziel der Aktion war es, ein Produkt zu haben, was bei der Migration von einem Telefon weg hilft. Dazu sollte Fone2Phone alles, was das Telefon an Daten enthält, aus diesem herausholen und in die jeweils zuständigen Apple-Applikationen befördern.

Das ist für sich genommen natürlich recht wenig (wenn auch technisch anspruchsvoll), darum haben wir uns von vornherein das Ziel gesetzt, mit dem Produkt auf der Macworld möglichst viele Preise abzusahnen. (Was auch  geklappt  hat. :)

Aber das ist alles nur Vorrede (und Stolz, schließlich hab ich damit gezeigt, was ich kann). Also auf zum eigentlichen Zweck dieses Posts.

Animation des Übergangs

Die Animation. Damit Fone2Phone wirklich geil aussieht, haben wir tief in die Trickkiste gegriffen ('Wir' ist in diesem Zusammenhang mein Kollege  Andreas).

Denn damit die Animation richtig gut aussieht, überlagern wir drei Elemente.

  1. Eine Animation, die die beiden Views austauscht
  2. Eine variable Geschwindigkeit, das heißt die Animation beginnt langsam, beschleunigt sich dann und wird am Schluss wieder langsam.

Bis hierher wäre ich auch darauf gekommen - aber der eigentliche Geniestreich liegt in dem letzten Element, das da noch oben drauf kommt:

  1. Die Views werden mit dem Hereinschieben eingeblendet / mit dem Herausschieben ausgeblendet.

Dieses letzte Element macht die Animation soo viel besser - obwohl es in der Komposition zuerst bewust überhaupt nicht wahrgenommen wird.

Und das ist die Lektion, die ich heute mitgenommen habe.

  • Posted: 2008-02-04 21:56 (Updated: 2009-10-24 16:26)
  • Author: dwt
  • Categories: software
  • Comments (0)

Worktimer Erweitern

Ich würde ja gerne eine Erweiterung für den Worktimer bauen - z.B. ein Widget, das es erlaubt, einfacher zu tracken, dass man etwas getan hat.

Dazu hab ich mir auch schon was überlegt - und zwar würde ich das in etwa so machen:

How I'd like the worktimer-widget to look.

Links kann man mit Start/Stop einfach sagen, dass man losgelegt hat bzw. gerade fertig geworden ist, und auf der Anzeige rechts soll die Gesamtzeit der letzten Sitzung plus vielleicht noch die Summe dieses Tages und dieser Woche zu sehen sein.

Das Problem
meine eigenen Graphiker-Techniken reichen leider noch nicht ganz aus, um so etwas zu implementieren.
Die Lösung
Da das hier Open Source-Software ist, würde ich mich über eine Mail an spamfaenger [at] gmx.de mit einem Hilfsangebot freuen. :)
  • Posted: 2007-08-24 23:47 (Updated: 2009-10-24 16:26)
  • Author: dwt
  • Categories: software
  • Comments (0)

Worktimer

The Worktimer in action! When I wrote my Diplom Thesis (Master's Thesis) I needed something to track how much time I spent on it each week. Well, what better excuse to play a bit with core-data and cocoa-bindings. :)

In the app you can add new times (the + button). It's pre-filled to the current time, but you can always insert the current time with <Command-T>. You can also always adjust the previous entries by selecting them down in the backlog and adjusting the values.

Also note the neat weekly summary available in the Window Menu (or via <Command-R>).

  • Posted: 2007-08-24 23:29 (Updated: 2007-08-25 10:24)
  • Author: dwt
  • Categories: software
  • Comments (0)

!ScreenLight

Screenshot of the Software in Action Ever wondered how useful it would be to always have a Flashlight with you?

Well, stop wondering, because you have! That is, you do if you have a mobile phone with you that has a screen that is perfectly capable of displaying pure white at maximum brightness and is programmable in Java.

There you have it, a ScreenLight!

To install, just send the jar-file to your phone via Bluetooth file transfer (or whatever method you prefer), after that the phone should ask you where you want to install the app (for me that is in "Games" or in "Applications"). Thats it!

Many thanks to prom who showed me how to do this!

  • Posted: 2007-07-24 12:04 (Updated: 2007-08-25 10:38)
  • Author: dwt
  • Categories: software
  • Comments (0)

Bisher unveröffentlichte Features von Leopard

 Die detaillierte Beschreibung der WWDC Sessions ist heute online gegangen und man findet darin interessante Details zu bisher unveröffentlichten neuen Features von Leopard.

  • Neue Funktionen für den Package Installer: Offenbar plant Apple das installieren von Programmen nur für einzelne Benutzer einfacher zu machen und Signierte Pakete zu unterstützen. Dazu ist von "Internet Download Packages" und neuen Receipt Tools die Rede. (Von "Creating Custom Installers with Leopards New PackageMaker")
  • Core Text: Apple will offenbar ein neuer Framework für Schriftbehandlung, Rendering und Layout einführen. (Von "Core Text Lab")
  • Neue Leopard Kernel Debugging Tools: Apple verspricht einen "Live Kernel Debugger", neue Konsolenkommandos "trace", "latency", "spindump" und "stackshot". (Von "Fundamentals of Kernel Debugging")
  • Dictionary Development Kit: Offenbar will Apple neue Werkzeuge zur Übersetzung von Programmen bereitstellen. (Von "Input Method & Internationalization Lab")
  • Versionierung in Core Data: Core Data Schemas können Versioniert werden und es gibt offenbar hilfsmittel bei der Migration von früheren Versionen. (Von "Managing Schema Versioning and Data Migration in Your Core Data Application")

Das wars. Nicht viel, aber doch ein kleiner Blick auf die vielen von Steve versprochenen - bisher verschwiegenen - Features.

  • Posted: 2007-04-04 02:19 (Updated: 2009-10-24 16:02)
  • Author: dwt
  • Categories: software
  • Comments (0)