Was bedeutet das ?
Thomas Mell
- perl
Hi Gemeinde,
ich bin über ein paar Zeilen Perl gestolpert die ich nicht verstehe:
my $spin = IO::File->new_tmpfile;
my $spout = IO::File->new_tmpfile;
my $sperr = IO::File->new_tmpfile;
local(*SPIN, *SPOUT, *SPERR) = ($spin, $spout, $sperr);
In den ersten 3 Zeilen werden wohl Dateihandels auf 3 Temporäre Dateien angelegt ?!
Aber was zum Himmel bedeutet '*SPIN' etc. (besonders das '*')?
vielen Dank schon mal
Thomas Mell
Halihallo Thomas
my $spin = IO::File->new_tmpfile;
my $spout = IO::File->new_tmpfile;
my $sperr = IO::File->new_tmpfile;local(*SPIN, *SPOUT, *SPERR) = ($spin, $spout, $sperr);
In den ersten 3 Zeilen werden wohl Dateihandels auf 3 Temporäre Dateien angelegt ?!
jups. Wobei du nicht den Handle per se, sondern eine Referenz (im Kontext sogar eine
IO::File - Instanz) auf ihn bekommst.
Aber was zum Himmel bedeutet '*SPIN' etc. (besonders das '*')?
$spin ist im Beispiel eine Referenz auf den Dateihandle. Um nun zum "Dateihandle" (das
wohl bekannteste Beispiel ist STDOUT, STDERR) an sich zu kommen, kannst du diesen im
lokalen Scope definieren und mit *SPIN = $spin setzen. Das * bedeutet 'Adresse von', die
physikalische Adresse des Handles SPIN wird also mit der referenzierten Adresse von
$spin gefüllt, somit ist dann SPIN der Handle, den $spin referenziert. Hulla, jetz hab
ich selbst mich verwirrt ;-)
Klar? - Wenn nicht, kann ich's ja von einer anderen Seite aus zu erklären versuchen.
Viele Grüsse
Philipp
Hi Philipp,
das habe ich jetzt nur halb verstanden ;)
Ich Trampel habe auch noch ne Zeile Code vergessen, hier nochmal der ganze Code.
my $spin = IO::File->new_tmpfile;
my $spout = IO::File->new_tmpfile;
my $sperr = IO::File->new_tmpfile;
local(*SPIN, *SPOUT, *SPERR) = ($spin, $spout, $sperr);
open3("<&SPIN", ">&SPOUT", ">&SPERR", @cmd);
Gibt mir * nun die physikalische Adresse des Dateihandels oder die Adresse auf die der Handle verweist? (oder ganz was anderes *g*).
Verwirrend ist in diesem Kontext auch das & in der open3-Anweisung.
Vielen Dank und schöne Grüße
Thomas
Halihallo Thomas
my $spin = IO::File->new_tmpfile;
my $spout = IO::File->new_tmpfile;
my $sperr = IO::File->new_tmpfile;
local(*SPIN, *SPOUT, *SPERR) = ($spin, $spout, $sperr);
open3("<&SPIN", ">&SPOUT", ">&SPERR", @cmd);Gibt mir * nun die physikalische Adresse des Dateihandels oder die Adresse auf die der Handle verweist? (oder ganz was anderes *g*).
Um kurz zu antworten: Ersteres. Das * vor dem SPIN/SPOUT/SPERR gibt dir einen Pointer
mit der physikalischen Adresse des Dateihandel-structs zurück. Da du in Perl mit der
Adresse nix anfangen kannst, siehst du in keinem Perlprogramm print *STDOUT "test" ;-)
Vielleicht hast du es ja auch schon den Verweisen im anderen Posting entnehmen können:
Das * - Zeug wird für die Symbol-Tabelle benutzt. Diese wird von Perl intern benutzt, um
Variablen eines Moduls zu referenzieren. Das Symbol '*' entstammt der Syntax von C/C++
und bedeutet 'Adresse-von', also nicht der Wert der Variablen selber, sondern deren
Adresse im Speicher (Analog aber nicht gleich zu Referenz '' in Perl).
Einige Gedanken, um das ganze etwas deutlicher Darzustellen:
Die Symbol-Tabelle stellt eine Art assoziatives Array (Hash) dar, welche(r|s) die
(Variablen-) Namen einem Speicher zuweisen; der Wert eines Tupels/Datensatzes ist gleich
einem Pointer (ich habe bewusst nicht Referenz gesagt, da diese Perlintern komplett
anders gehandhabt werden) auf die entsprechende Speicherstelle. Setzt du nun *SPIN =
$spin, überschreibst du den Wert der Symbol-Tabelle mit der Referenz in $spin; der alte
Pointer auf eine Speicheradresse wird durch den neuen ersetzt und somit ist SPIN gleich
mit dem durch $spin referenzierten Handle.
Um es noch anders zu sagen: Wenn *SPIN mit $spin "ersetzt" (ums noch etwas komplizierter
zu sagen: der Pointer *SPIN wird mit der referenzierten Adresse des Skalars $spin
überschrieben) wird, und du dann auf SPIN zugreifst, wird perl in der Symboltabelle
unter *SPIN nachsehen, kriegt eine Speicheradresse, welche auf ein Handle-Struct
(welches durch $spin ebenfalls referenziert wird) zeigt und verwendet dieses.
Verwirrend ist in diesem Kontext auch das & in der open3-Anweisung.
Das '&' alleine bedeutet nichts, zusammen mit '<' oder '>' bedeutet es, wie der Handle
benutz wird (lesen/schreiben). Wenn du ein '<&' hast, bedeutet dies, dass der angegebene
Handle für den Parentprozess geschlossen wird und der Childprozess von ihm lesen kann.
Bei '>&' wird der Childprozess Daten direkt an den Handle _senden_. open3 ist für das
kommunizieren zwischen Parent und Childprozess mit drei Handles gedacht; bei jedem
aufruf von open3 wird also ein neuer Prozess generiert (mit dem man eben über die
Handles kommunizieren kann).
Viele Grüsse
Philipp
Halihallo Thomas
Klar? - Wenn nicht, kann ich's ja von einer anderen Seite aus zu erklären versuchen.
perldoc perldata; Section über "Typeglobs and Filehandles".
perldoc perlmod; Section über "Symbol Tables"
Viele Grüsse
Philipp