Variable our & use vars
alligator
- perl
Hi zusammen,
kurz vorweg. Ich rufe mit require() aus meinem Hauptscript ein 2tes Script auf. Jedoch soll an dieses 2 Script einige PArameter übergeben werden.
Naja und auf der Suche wie ich das mache, bin ich jetzt bei our und use vars gelandet.
Hier mein Script 1:
#!/usr/bin/perl -w
use strict;
use vars;
our $x = "10";
require "2.pl";
print "\nVorbei";
und hier 2.pl:
#!/usr/bin/perl -w
use strict;
use vars;
our $x;
$x += 5;
print "\n$x";
Naja das funktioniert auch soweit (bis auf das -w mir einige Warnings ausgibt). Nun ist mir aber nicht ganz klar was use vars genau macht ? Denn es funktioniert auch, wenn ichs draussen lasse. Habe schon die perldoc durchgelesen aber werde ehrlichgesagt nicht schlauer draus. Und meine zweite Frage ist, warum ich our $x auch in 2.pl schreiben muss ? Es wurde doch schon im ersten als our deklariert ?
Würde mich über aufklärung freuen. Danke.
cu
alligator
Hallo Alligator,
also in deinem Beispielscript versuchst du, sowohl mit require als auch mit use zu arbeiten. Versuch mal, nur mit use zu arbeiten. Dann musst du allerdings die zweite Datei mit der Endung .pm statt .pl versehen und dich ausserdem mal mit den Moeglichkeiten befassen, die use bietet.
Kannst ja mal mit diesen Abschnitten anfangen:
http://selfhtml.teamone.de/cgiperl/module/intro.htm#require_use
http://selfhtml.teamone.de/cgiperl/module/intro.htm#use_erweitert
http://selfhtml.teamone.de/cgiperl/funktionen/module.htm#use
Ein Beispiel, wozu "use vars" dient, findest du bei:
http://selfhtml.teamone.de/cgiperl/funktionen/kontrolle.htm#my
viele Gruesse
Stefan Muenz
Hi,
Kannst ja mal mit diesen Abschnitten anfangen:
http://selfhtml.teamone.de/cgiperl/module/intro.htm#require_use
http://selfhtml.teamone.de/cgiperl/module/intro.htm#use_erweitert
http://selfhtml.teamone.de/cgiperl/funktionen/module.htm#use
Ein Beispiel, wozu "use vars" dient, findest du bei:
http://selfhtml.teamone.de/cgiperl/funktionen/kontrolle.htm#my
werds mir mal zu Gemüte führen. Danke.
cu
alligator
Hoi,
[...]
Naja das funktioniert auch soweit (bis auf das -w mir einige
Warnings ausgibt).
Kein Wunder ;-)
Nun ist mir aber nicht ganz klar was use vars genau macht ?
'use vars' ist dasselbe wie 'our', nur aus einer aelteren
Perl-Version. 'our' wurde erst mit Perl 5.6.0 eingefuehrt. Die
richtige Anwendung von 'use vars' waere:
use vars qw($GLOBALVAR1 $GLOBALVAR2 $GLOBALVARn);
Das entspricht
our ($GLOBALVAR1, $GLOBALVAR2, $GLOBALVARn);
Denn es funktioniert auch, wenn ichs draussen lasse.
Siehe oben.
Und meine zweite Frage ist, warum ich our $x auch in 2.pl
schreiben muss ? Es wurde doch schon im ersten als our
deklariert ?
Weil es einen anderen Namespace hat. Lass das 'our $x' weg und
schreib stattdessen
$main::x
wenn du damit arbeiten willst. Alternativ geht auch '$::x', was ich
persoenlich aber fuer eher ekelig halte. Du kannst auch ein
richtiges Modul schreiben und die Variable in den Namespace
des Scripts exportieren, siehe dazu aber perldoc perlmod.
Gruesse,
c.j.k
HI,
erstmal Danke für die Hilfe, jetzt ist mir einiges klarer ...
Weil es einen anderen Namespace hat. Lass das 'our $x' weg und
schreib stattdessen
$main::x
Für was steht den $main bzw. was ist/macht diese Variable ?
Könnt ich diese Variable auch $hund nennen oder ist das ne Umgebungsvariable wie $_ oder so?
Danke.
cu
alligator
Nachtrag: ...
Script 1:
#!/usr/bin/perl -w
use strict;
our $x = "10";
require "2.pl";
print "\nVorbei";
Script 2:
#!/usr/bin/perl -w
use strict;
$main::x;
$x += 5;
print "\n$x";
So tut es aber auch nicht ...
Fehler:
Name "main::x" used only once: possible typo at E:\Proggen\Perl\1.pl line 5.
Variable "$x" is not imported at 2.pl line 4.
Variable "$x" is not imported at 2.pl line 5.
Global symbol "$x" requires explicit package name at 2.pl line 4.
Global symbol "$x" requires explicit package name at 2.pl line 5.
Compilation failed in require at E:\Proggen\Perl\1.pl line 6.
Hmmm ?!?!?
cu
alligator
Hoi,
erstmal Danke für die Hilfe, jetzt ist mir einiges klarer ...
Schoen
Weil es einen anderen Namespace hat. Lass das 'our $x' weg und
schreib stattdessen
$main::x
Für was steht den $main bzw. was ist/macht diese Variable ?
Das ist keine Variable. Das bezeichnet den Namespace 'main', den Namespace,
den das ausfuehrende Script hat. Die Variable ist immer noch '$x'.
Könnt ich diese Variable auch $hund nennen oder ist das ne
Umgebungsvariable wie $_ oder so?
Nein, es ist keine Variable. Es bezeichnet einen Namespace. Und wenn du ein
Modul 'hund' hast, dann kannst du auch $hund::x schreiben, ja ;-)
[... kaputtes Perl ...]
Das geht so nicht. Schreibs so:
Script.pl:
#!/usr/bin/perl -w
use strict;
use Module;
$Module::x += 5;
print "$Module::x\n";
----------------------------
Module.pm:
package Module;
our $x = 10;
1;
Zur Erklaerung: das 'use Module' bindet die Datei 'Module.pm' (Achtung,
Case-Sensitive!) ein. Das 'package Module;' leitet ein Modul und damit auch
einen eigenen Namespace ein. Durch das 'our $x' registrierst du die Variable
'$x' in den Symbol-Tabellen des Moduls 'Module'. In den Symbol-Tabellen sind
alle globalen Variablen und alle Typeglobs eingetragen; das kannst du sehr
schoen in dem folgenden Script sehen:
#!/usr/bin/perl -w
use vars qw($hallo);
my $hallo1;
print join "\n" => keys %::;
Die Ausgabe ist:
@
stdin
STDIN
"
_<./test.pl
stdout
STDOUT
$
_<perlmain.c
BEGIN
_</usr/libdata/perl/5.00503/vars.pm
^H
ENV
IO::
UNIVERSAL::
/
hallo <----- HIER STEHT UNSERE VARIABLE $hallo
vars::
ARGV
0
^R
stderr
STDERR
^W
DynaLoader::
^X
main::
Carp::
DB::
INC
_</usr/src/gnu/usr.bin/perl/libperl/../../../../contrib/perl5/universal.c
]
CORE::
Du siehst also an diesem Beispiel, lexikalisierte Variablen, also
'my'-Variablen, werden *nicht* in die Symbol-Tabelle eingetragen.
Aber Perl verzeichnet nicht nur globale Variablen in der Symbol-Tabelle,
sondern auch alle Module. Wenn ich also mal dein Beispiel zu Rate ziehe:
@
stdin
_<./test.pl
^H
strict::
UNIVERSAL::
^R
^W
DynaLoader::
^X
main::
Carp::
INC
_</usr/src/gnu/usr.bin/perl/libperl/../../../../contrib/perl5/universal.c
]
_
"
STDIN
STDOUT
stdout
_</usr/libdata/perl/5.00503/strict.pm
_<perlmain.c
$
BEGIN
_</usr/libdata/perl/5.00503/vars.pm
ENV
IO::
_<Module.pm
/
vars::
0
ARGV
STDERR
stderr
DB::
Module:: <--- HIER IST DEIN MODUL
CORE::
Ich hoffe, jetzt verstehst du es etwas besser. Wenn nicht, frag einfach nach.
Wenn dich die Materie interessiert, wuerde ich dir das Buch 'Effektiv Perl
programmieren' empfehlen -- das ist *wirklich* gut :-)
Gruesse,
c.j.k
Hi,
erstmal danke für die ausführlich Antwort.
Super so funktioniert es auch :o)
Danke !!!
Aber eins hab ich noch nicht ganz. Was sind den diese Packages ?
Also was macht:
#!/usr/bin/perl -w
package Hunde;
our $x = 0;
1;
Wäre nett wenn du mir das relativ Simpel erklären könntest ...
cu
alligator
Hoi,
Aber eins hab ich noch nicht ganz. Was sind den diese Packages?
Also was macht:
#!/usr/bin/perl -w
package Hunde;
our $x = 0;
1;
Wäre nett wenn du mir das relativ Simpel erklären könntest ...
Habe ich doch gesagt. Es leitet ein Modul und einen Namespace ein.
Gruesse,
c.j.k
Hi,
ehrlichgesagt kann ich mit dieser Erklärung nicht wirklich viel anfangen. Was bedeutet es wenn man einen Namensraum (Namespace) einleitet ?
Was ein Modul einbinden bedeutet, ist mir eigentlich klar, aber halt nicht das mit den packages ...
cu
allgiator
Hi,
nächstes Problem.
Mein Errorlog sagt:
Use of reserved word "our" is deprecated at auswahl.pl line 13.
Global symbol "$x" requires explicit package name at auswahl.pl line 13.
Und in dieser Zeile steht nur:
our $x = 0;
Und bis jetzt hab ich noch garnix eingebunden mir use oder require ...
Brauche Hilfe .. Danke !
cu
alligator
Hi auch,
Use of reserved word "our" is deprecated at auswahl.pl line 13.
our $x = 0;
welche Perl-Version? ("perl -v")
Viele Grüße
Michael
Hoi,
Mein Errorlog sagt:
Use of reserved word "our" is deprecated at auswahl.pl line 13.
Global symbol "$x" requires explicit package name at auswahl.pl
line 13.
Und in dieser Zeile steht nur:
our $x = 0;
Wie gesagt. 'our' gibt es erst seit Perl 5.6.0. Benutze 'use vars
qw($x);'.
ehrlichgesagt kann ich mit dieser Erklärung nicht wirklich viel
anfangen. Was bedeutet es wenn man einen Namensraum (Namespace)
einleitet ?
Ok, nochmal. Also, jedes Modul hat einen eigenen Namens-Raum. Das
bedeutet, dass gleichlautende Variablen in zwei Modulen trotzdem
verschieden sind; probier mal das hier:
#!/usr/bin/perl
$x = 0;
package hund;
$x = 10;
package katze;
$x = 20;
package main;
print $x,"\n";
print $hund::x,"\n";
print $katze::x,"\n";
Du siehst hier, dass es genau eine Variable gibt ($x), die aber doch
3x repraesentiert ist: jedesmal in einem anderen Namensraum. Der
Default-Namensraum ist 'main', ein ausfuehrendes Script hat in jedem
Fall diesen Namensraum, es sei denn, es leitet durch 'package' einen
anderen ein.
Was ein Modul einbinden bedeutet, ist mir eigentlich klar, aber
halt nicht das mit den packages ...
Lies mal perldoc perlmod (http://www.perldoc.com/perl5.6.1/pod/perlmod.html),
das ist zu diesem Thema sehr aufschlussreich.
Gruesse,
c.j.k