Moin Moin!
Ich halte Perls Taint-Mode bei allen Programmen, die Daten aus dem Netz oder von unpriviligierten Benutzern verarbeiten, für einen der größten Vorteile. Denn er zwingt dazu, Eingaben zu validieren. Vergißt man das Validieren, bricht Perl das Programm gnadenlos ab, sobald man mit unvalidierten Daten an irgendwelche kritischen Funktionen herangeht. Natürlich kann man an der Stelle auch Mist bauen und schlicht jeden Müll validieren, aber das ist eine andere Geschichte.
Dazu kommt DBI, das eine EINHEITLICHE Schnittstelle für alle möglichen Datenbanken anbietet, von winzigen Flat-File-DBs bis hin zu riesigen DB-Clustern. Verkneift man sich RDBMS-spezifische SQL-Erweiterungen, kann man Applikationen schreiben, die auch tatsächlich von Flat-File-DBs bis zu DB-Clustern ohne einzige Änderung am Code laufen.
Oh, und ein zentrales Repository mit Modulen für wirklich jedes noch so verrückte Problem habe ich so noch bei keiner anderen Sprache außer TeX gesehen. (OK, technisch gesehen ist es nicht zentral, sondern ein Netz von Mirror-Servern. Aber das sieht man im Alltag nicht.)
An PHP stört mich vor allem, dass man an einigen Stellen gegen Einsteins "so einfach wie möglich, aber nicht einfacher verstoßen hat", als man Perl abkupferte. $, @ und % haben einen Sinn, den man auf der PHP-Seite anscheinend nicht verstanden hat. Kontext ist in PHP ein Fremdwort, ebenso Namespaces.
Perls einheitliche Sort-Funktion, der man bei Bedarf eine Vergleichsroutine mitgibt, kann alles nach beliebigen Kriterien sortieren. In PHP muß man sich mit einem großen Haufen Sortierfunktionen herumschlagen, die alle auf irgendeinen besonderen Vergleich spezialisiert sind. Analoges gilt z.B. auch für Such- und Ersetzfunktionen. PHP ist inkonsistent. Funktionen haben ausgewürfelte Namen, erwarten Parameter in überraschend unterschiedlicher Reihenfolge, und haben merkwürdige Rückgabewerte.
PHP hat viel zu viel Zeug im Sprachkern, der eigentlich in Module gehört. (z.B. Datenbank-Schnittstellen). Perl 4 hatte das Problem ebenfalls, weil zu der Zeit noch niemand auf die Idee gekommen war, Schnittstellen dynamisch nachzuladen. Das war vor 18 Jahren. PHP schlägt sich damit heute noch rum.
PHP "Magic Quotes" - mir fehlen die Worte. Offenbar hat man allerdings mittlerweile eingesehen, dass das nicht die beste Idee war.
Mehr:
Klar, Perl hat auch Macken und Altlasten:
* Support für DBM-Files gehört nicht in den Kern, sondern in Module. Ebenso SysV-IPC, Sockets, getpwnam/getgrnam/gethostbyname/...-Funktionen. Reste von Perl 4.
* eval { BLOCK }; if ($@) { ... }
hieße besser try/catch/finally.
* wantarray hieße besser wantlist.
* warnings und strict sind nicht standardmäßig eingeschaltet.
* Features von 5.10 (defined-or-Operator, switch-case mit Smart Matching alias given-when-default, say) müssen explizit über use feature 5.10
eingeschaltet werden, damit alte Scripte nicht auf die Nase fallen.
* defined-or kommt viel zu spät
* say() ist eine nette Idee, aber so etwas triviales kann man auch selbst als Funktion implementieren, wenn man es braucht. Andererseits spart einem die Implementation von say() im Kern genau diese Mühe.
* Perl steht tierisch auf Kriegsfuß mit Dateinamen unter Windows, weil es nicht die Unicode-APIs mit den "langen" Dateinamen nutzt.
* Die fork()-Emulation unter Windows ist eine Krücke. Besser als nichts, aber nicht sonderlich kompatibel mit Scripten, die Unix-Verhalten erwarten.
* perlcc, JPL
* Pseudo-Hashes
* In-place-Sorting ist nur eine interne Optimierung, kann aber nicht explizit gecoded werden. @a=sort @a;
wird ab 5.10 optimiert, ich hätte aber lieber so etwas wie sort_inplace(@a)
gesehen.
* $^T alias $BASETIME und insbesondere die jedes mal umgerechneten Rückgabewerte von -M, -A und -C sind grober Unfug. Andererseits kann man natürlich auch stat benutzen.
* stat, gmtime und localtime liefern im List-Kontext Arrays statt Hashes mit brauchbaren Namen. File::stat bringt wenigstens für stat() Abhilfe.
* open modifiziert sein erstes Argument (Typeglob oder Scalar), statt ein File-Objekt zurückzugeben
* open mischt Dateinamen und Dateimodus (mittlerweile kann man Modus und Namen getrennt angeben)
* open und andere Funktionen erzeugen weder Warnungen noch Fehler, wenn ein Perl-String mit eingebetteten NUL-Bytes an eine darunter liegende C-Funktion übergeben und dadurch abgeschnitten wird. (Poision NUL byte)
Alexander
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".