Tuesday, September 22, 2009

Noch mehr zu "open"...

In meinem letzten Blog-Post bin ich ja schon auf verschiedene Sachen bezüglich der Perl-Funktion open eingegangen. Das bezog sich aber alles auf mögliche Probleme.

Mit dem heutigen Blog-Post möchte ich noch zwei Themen ganz kurz ansprechen, die open sehr mächtig machen:

I/O-Layer

Seit Perl 5.6.0 gibt es sogenannte I/O-Layer, mit denen man die Daten durch einen "Umwandler" schicken kann. Mit den I/O-Layern kann man z.B. sehr einfach Dateien in ISO-8859-1 sehr leicht in UTF-8 umwandeln:

open my $fh, '<:encoding(iso-8859-1)', $file or die $!;
open my $ofh, '>:encoding(utf-8)', $new_file or die $!;
print $ofh $_ while <$fh>;
close $ofh;
close $fh;

So etwas verwende ich teilweise in der Vorbereitung für neue Ausgaben vom Perl-Magazin.

In einigen alten Quellen wird als utf8-Layer auch einfach ":utf8" verwendet. Das kann aber Probleme machen, da die Daten nicht richtig (de-)kodiert werden, sondern einfach das UTF-8-Flag setzt.

Sollen alle Aufrufe von open mit einem bestimmten I/O-Layer verwendet werden, kann man auch das open-Pragma verwenden:

use open ":encoding(utf-8)";

Mit den Layern kann man aber nicht nur mit "Zeichensätzen" arbeiten, sondern auch die Daten z.B. gleich verschlüsseln wenn sie in die Datei geschrieben werden und beim Auslesen entschlüsseln. Dafür gibt es dann Module wie PerlIO::via::CBC

open mit Pipe

Wofür man "open" noch verwende kann, ist eine einfache Art und Weise, mit einem anderen Programm zu "kommunizieren". Wie man also Daten an andere Programme schicken kann, die diese auf STDIN erwarten. Oder Werte von dem Programm empfangen, die dieses auf STDOUT schreibt. Dazu kann man die Pipe verwenden.

So kann man z.B. einfach Daten an ein Programm schicken:

open my $fh, '| /ein/programm.exe' or die $!;
print $fh "Mein Name\n";
# programm.exe erwartet einen Namen auf STDIN
close $fh;

Siehe auch:

3 comments:

Chas. Owens said...

That last example should be

open my $fh, "-|", "/ein/programm.exe'"
    or die "Konnte nicht ausgeführt werden programm.exe: $!";

for a read filehandle and

open my $fh, "|-", "/ein/programm.exe"
    or die "Konnte nicht ausgeführt werden programm.exe: $!";

for a write filehandle. Note, Google Translate gave me that German phrase, so I have no idea how proper it is for the situation. The English phrase I translated is "Could not run".

Basically, the - goes on the side of the pipe the program would have been on. This form also allows you to pass the arguments to the program as a list to the open function instead of as part of a string that is subject to bad interactions with the shell.

ReneeB said...

Hi Chas,

thanks for your comment. The phrase you used is ok!

Cheers,
Renee

moritz said...

Das Problem mit :utf8 tritt nur auf, wenn die Eingabedaten kein gültiges UTF-8 - wenn sie gueltig sind, hat :utf8 auch kein Problem.

Allerdings kann man sich dessen häufig nicht sicher sein, deswegen ist :encoding(UTF-8) besser.