Hallo,
danke für die informativen Antworten!
renee+2009-01-15 08:15:47--Den -C-Switch in der Shebang ist nutzlos (im Gegensatz zum -C in der Kommandozeile), weil er bisher nicht richtig funktioniert hat und in Perl 5.10 rausgeworfen wurde.
Auch beim Aufruf von "perl -w -CSD test-unicode" ergibt sich keine Änderung am Verhalten des Scripts; eine Änderung z.B. auf "-C0" im Shebang wirkt sich aber durchaus aus (und sorgt dafür, dass auch mein open() kein utf8 mehr liefert). Das Perl, das hier zum Einsatz kommt, ist auch noch ein 5.8.5 (auf einem CentOS 4.5), auch wenn das Script natürlich auch mal unter Perl 5.10 laufen sollte. Aber das erscheint mir im Moment eher als sekundäres Problem; perl -CSD tut ja auch jetzt schon nicht, was ich meine, was es tun sollte.
renee+2009-01-15 08:15:47--Am geschicktesten wäre es wohl, IO::Util zu patchen und den Patch auch an den Autor schicken. Oder ein eigenes Wrappermodul drumbauen, das eine eigene slurp-Funktion bereitstellt, in der Du den Filehandle erstellst und den Filehandle mittels "binmode $filehande, ':encoding(utf-8)'" auf UTF-8 umstellst. Oder Du schreibst gleich eine eigene slurp-Funktion.
Okay, ich hatte bewusst gesagt, dass ich IO::Util idealerweise nicht patchen müssen will, weil das letztlich nur ein Beispiel war und ich nach einer generalisierten Lösung suche - deshalb habe ich die Problemstellung ja auch derart zu abstrahieren versucht, dass gar kein externes Modul (außer meinem eigenen zur Demonstration der Problemstellung) zum Einsatz kommt. Denn der Einsatz von Modulen ist in meinem ganz konkreten Fall noch deutlich komplexer, weil IO::Util nur indirekt zum Einsatz kommt: Genaugenommen benutze ich CGI::Builder mit dem Modul CGI::Builder::Magic, das eine Anbindung zu Template::Magic darstellt, das wiederum die Templates einliest. Es wäre also nicht damit getan, IO::Util zu patchen, sondern ich müsste dann auch den ganzen Rest bis hin zum eigentlichen High-Level-Modul CGI::Builder::Magic patchen. Und zwar dergestalt, dass ich hier nicht einfach ein Filehandle übergebe, sondern schon irgendwie mitteilen müsste, dass die darunterliegenden Module bitte auch bei allen weiteren Dateioperationen den utf8-Layer benutzen sollten. Denn:
Die Variante mit der Übergabe eines fertig gelayerten Filehandles, die ist offiziell vorgesehen und funktioniert auch prima. Templates können aber auch include-Anweisungen enthalten und weitere Templates einbinden, und spätestens dann ist wieder Essig, weil es in diesem Fall ja Template::Magic (mittels IO::Util) ist, das das einzubindende Template öffnet, und nicht ich. Es würde also bei einer sauberen Lösung kein Weg daran vorbeiführen, Template::Magic die gewünschten Layer mitzuteilen, damit es diese an IO::Util übergeben kann, damit jenes sie dann auch bei jedem open() beachtet, das es angeregt durch ein include selbst durchführt.
moritz+2009-01-15 09:27:22--Dein Versuch, ein Modul "von aussen" Unicode-tauglich zu machen ist genauso verständlich, wie es zum Scheitern verurteilt ist. Spätestens wenn das Modul explizit IO-Layer angibt (was ich bei Module, die selbst mit IO anfangen, für recht wahrscheinlich halte) kann das gar nicht mehr gehen, selbst wenn es ansonsten einen Mechanismus gäbe.
Erstmal freut mich, dass mein Wunsch an sich verständlich zu sein scheint. :-)
Mal etwas flapsig ausgedrückt: Ich will kein Modul Unicode-tauglich machen. Ich will, dass ein Modul das richtige tut, wenn es sich einfach gar nicht um den ganzen Layerkrempel kümmert. Es soll sich zurücklehnen und sagen: "Wenn du willst, dass ich bei einem open() den $utf8_oder_sonstwas-Layer benutze, dann sag das nicht mir: Sag es PerlIO. Ich kümmere mich selber nicht um Layer, sondern benutze einfach die, auf die dein PerlIO eingestellt ist." - Dass ein Modul unabhängig davon natürlich _auch_ selber Layer setzen kann, steht dabei ja außer Frage. Mein Beispielcode gibt nebenbei selber keinerlei IO-Layer an, die den "Default" überschreiben würden - und trotzdem funktioniert's nicht.
Mir erscheint es einfach als wenig sinnvoll, jedem einzelnen Modul beibringen zu müssen, welchen Layer es beim Öffnen von Dateien benutzen soll, wenn Perl "eigentlich" eine Möglichkeit mitbringt, den Default-Layer selbst zu bestimmen (und sowohl man perlrun als auch man perluniintro legen das eigentlich nahe:
You can enable automatic UTF-8-ification of your standard file handles, default "open()" layer, and @ARGV by using either the "-C" command line switch or the "PERL_UNICODE" environment variable. Und es erscheint mir auch einfach wie ein Fehler, wenn ich mir in meiner TestUnicodeModule.pm den Wert von ${^UNICODE} anschaue und feststelle, es ist auf utf8 für IO-Operationen eingestellt, aber meine IO-Operationen laufen dann faktisch gar nicht über den utf8-Layer.
Sagt mir "Stimmt, blöd, ist aber so", und ich bin still ... wenngleich unglücklich.
Danke und viele Grüße,
Jonas
PS: Wenn's wirklich so ist, wäre das eine gute Erklärung dafür, wieso Unicode mit Perl einfach keinen Spaß mehr machen will, sobald man Module abseits der ganz verbreiteten einsetzen will, in die die Autoren bereits explizit utf8-Support (oder generalisiert: Layer-Support) eingebaut haben. Dieses Geraffel jedem einzelnen CPAN-Modul separat beibringen zu wollen, scheint mir doch zum Scheitern verurteilt ...