Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

use und Variablen

0 views
Skip to first unread message

Helmut Schneider

unread,
Oct 29, 2009, 7:23:26 AM10/29/09
to
Hi,

# cat ./test.pl
#!/usr/bin/perl

use strict;
use warnings;

use lib "./";
our $myVarA = 1;
our $myVarB = 2;
use myTest;

print "\$myVarA = $main::myVarA\n";
print "\$myVarB = $main::myVarB\n";
# cat ./myTest.pm
package myTest;

print "\$myVarA = " . $main::myVarA . "\n";
print "\$myVarB = " . $main::myVarB . "\n";

1;
# perl ./test.pl
$myVarA =
$myVarB =
$myVarA = 1
$myVarB = 2
#

Soweit ich "use" verstanden habe, war das zu erwarten, da "use" vor dem
Kompilieren stattfindet. L�sen liese sich das "Problem", indem man
"use" durch "require" ersetzt.
Nun lese ich aber �berall, dass man "use" einem "require" wo immer
m�glich vorziehen soll. Ist obiges so eine Ausnahme, oder gibt es auch
einen "use"-Weg?

Ziel ist es, in einem package sicher zu stellen, dass bestimmte $main::
Variablen gesetzt wurden.

Danke und Gru�, Helmut

--
No Swen today, my love has gone away
My mailbox stands for lorn, a symbol of the dawn

ReneeB

unread,
Oct 29, 2009, 7:48:44 AM10/29/09
to
Du kannst Die Variablenzuweisungen in einem BEGIN-Block machen, das
wird dann auch zur Compile-Zeit ausgeführt. Dann kommt es nur noch auf
die Reihenfolge von BEGIN-Block und use-Anweisung an (der BEGIN-Block
muss *vor* der use-Anweisung kommen)...


#!/usr/bin/perl

use strict;
use warnings;

use lib "./";

BEGIN{

Helmut Schneider

unread,
Oct 29, 2009, 8:10:17 AM10/29/09
to
ReneeB wrote:

> BEGIN{
> our $myVarA = 1;
> our $myVarB = 2;
> }

Ah, bei BEGIN war ich sogar schon, aber vermutlich stimmte die
Reihenfolge nicht.

Merci, Helmut

Frank Seitz

unread,
Oct 29, 2009, 9:48:53 AM10/29/09
to
Helmut Schneider wrote:
>
> Ziel ist es, in einem package sicher zu stellen, dass bestimmte $main::
> Variablen gesetzt wurden.

Daran, dass es hakelig ist, l�sst sich ablesen, dass du ein
untaugliches Konzept verfolgst. Wenn du die Variablenwerte
$myVarA und $myVarB in myTest brauchst, �bergib sie
lieber als Parameter.

Gr��e
Frank
--
Dipl.-Inform. Frank Seitz
Anwendungen f�r Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Homepage: http://www.fseitz.de/
XING-Profil: http://www.xing.com/profile/Frank_Seitz2

Helmut Schneider

unread,
Oct 29, 2009, 11:14:49 AM10/29/09
to
Frank Seitz wrote:

> Helmut Schneider wrote:
> >
> > Ziel ist es, in einem package sicher zu stellen, dass bestimmte
> > $main:: Variablen gesetzt wurden.
>
> Daran, dass es hakelig ist, l�sst sich ablesen, dass du ein
> untaugliches Konzept verfolgst. Wenn du die Variablenwerte
> $myVarA und $myVarB in myTest brauchst, �bergib sie
> lieber als Parameter.

package myLdap;
sub connectToLdap ($$$$$) {
my $_ldapDomain = shift;
my $_DC = shift;
my $_port = shift;
my $_ldapBindUser = shift;
my $_ldapBindPass = shift;
[...]
}

Jetzt will ich ein zuf�lliges Passwort erstellen und ben�tige hierf�r:

@alphanumeric = ('a'..'z', 'A'..'Z', 0..9, '!', '?', '$', '/', '.',
'.', '-', '+', '=');
$pwLength = 10;

Ausserdem soll Net::LDAP $retries mal versuchen, sich mit dem Server zu
connecten:

$retries = 5;

Von den obigen 3 Werten sind aus meiner Sicht mindestens eine konstant
(@alphanumeric), die m�ssen nicht unbedingt jedesmal einer Subroutine
�bergeben werden. Das kostet doch auch Ressourcen, oder nicht (Objekt
�bergeben, Kopie erstellen, Kopie wieder l�schen)?!

"J. Strübig"

unread,
Oct 30, 2009, 7:10:39 AM10/30/09
to
Helmut Schneider schrieb:

> package myLdap;
> sub connectToLdap ($$$$$) {
> my $_ldapDomain = shift;
> my $_DC = shift;
> my $_port = shift;
> my $_ldapBindUser = shift;
> my $_ldapBindPass = shift;
> [...]
> }
>
> Jetzt will ich ein zuf�lliges Passwort erstellen und ben�tige hierf�r:
>
> @alphanumeric = ('a'..'z', 'A'..'Z', 0..9, '!', '?', '$', '/', '.',
> '.', '-', '+', '=');
> $pwLength = 10;
>
> Ausserdem soll Net::LDAP $retries mal versuchen, sich mit dem Server zu
> connecten:
>
> $retries = 5;
>
> Von den obigen 3 Werten sind aus meiner Sicht mindestens eine konstant
> (@alphanumeric), die m�ssen nicht unbedingt jedesmal einer Subroutine
> �bergeben werden. Das kostet doch auch Ressourcen, oder nicht (Objekt
> �bergeben, Kopie erstellen, Kopie wieder l�schen)?!
>

In dem Fall kannst du da auch default Werte in die Funktion (oder Modul)
einbauen, aber dazu musst du doch keine Variabeln global zug�nglich machen.

Und was die Performance angeht.

Wenn du diese Funktion millionenmal in dem Skript aufrufst, dann k�nnte
es u.U. eine Rolle spielen. Wobei aber globale Variabeln in der Regel
eher performancekiller sind.
D.h. du solltest nat�rlich auch pr�fen, ob die von dir gew�nschte
vorgehensweise wirklich eine Verbesserung bringt (z.b. mit dem Modul
Benchmark).

Struppi.

Helmut Schneider

unread,
Oct 30, 2009, 11:12:15 AM10/30/09
to
"J. Str�big" wrote:

Ich dachte mir, es macht die Sache vielleicht �bersichtlicher, wenn ich
das in main definiere.

> Und was die Performance angeht.
>
> Wenn du diese Funktion millionenmal in dem Skript aufrufst,

Unwahrscheinlich. :)

Peter J. Holzer

unread,
Oct 31, 2009, 7:30:06 AM10/31/09
to
On 2009-10-29 11:23, Helmut Schneider <jump...@gmx.de> wrote:
> # cat ./test.pl
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use lib "./";
> our $myVarA = 1;
> our $myVarB = 2;
> use myTest;
>
> print "\$myVarA = $main::myVarA\n";
> print "\$myVarB = $main::myVarB\n";
> # cat ./myTest.pm
> package myTest;
>
> print "\$myVarA = " . $main::myVarA . "\n";
> print "\$myVarB = " . $main::myVarB . "\n";
>
> 1;
> # perl ./test.pl
> $myVarA =
> $myVarB =
> $myVarA = 1
> $myVarB = 2
> #
>
> Soweit ich "use" verstanden habe, war das zu erwarten, da "use" vor dem
> Kompilieren stattfindet. L�ソスsen liese sich das "Problem", indem man
> "use" durch "require" ersetzt.
> Nun lese ich aber �ソスberall, dass man "use" einem "require" wo immer
> m�ソスglich vorziehen soll. Ist obiges so eine Ausnahme, oder gibt es auch
> einen "use"-Weg?

Es ist definitiv eine Ausnahme, dass Du in einem Modul, das mit use
eingebunden wird, Code hast, der sofort ausgef�ソスhrt wird und nicht nur
der Initialisierung dient. Normalerweise werden in Modulen nur
Funktionen bzw. Methoden definiert und eventuell ein paar Variablen
initialisiert. Wenn Du Dein myTest.pm so umschreibst:

package myTest;

sub print_vars {


print "\$myVarA = " . $main::myVarA . "\n";
print "\$myVarB = " . $main::myVarB . "\n";
}

1;

und dann in test.pl

myTest::print_vars()

aufrufst, wird es wie gew�ソスnscht funktionieren, weil der Aufruf zu einem
Zeitpunkt erfolgt, zu dem $main::myVarA und $main::myVarB schon
initialisiert sind.

Wenn $myVarA und $myVarB der Initialisierung von myTest dienen, dann
ist es vermutlich besser und lesbarer, Du �ソスbergibst sie gleich beim use:

use myTest (1, 2);
oder
use myTest (myVarA => 1, myVarB => 2);

und verwendest eine import-Routine in myTest.pm und dort package-globale
Variablen zu setzen.

Oder Du verwendest gleich den objektorientierten Ansatz:

use myTest;

$mytest = myTest->new(myVarA => 1, myVarB => 2);

dann kann die Methode new von myTest damit machen, was sie will (z.B. in
$mytest speichern, oder als package-globale Daten speichern oder
irgendwas damit berechnen und dann vergessen).

Ich tendiere meistens zu letzterem Ansatz.

hp

Peter J. Holzer

unread,
Oct 31, 2009, 7:45:29 AM10/31/09
to
On 2009-10-29 15:14, Helmut Schneider <jump...@gmx.de> wrote:
> Frank Seitz wrote:
>
>> Helmut Schneider wrote:
>> >
>> > Ziel ist es, in einem package sicher zu stellen, dass bestimmte
>> > $main:: Variablen gesetzt wurden.
>>
>> Daran, dass es hakelig ist, l�sst sich ablesen, dass du ein
>> untaugliches Konzept verfolgst. Wenn du die Variablenwerte
>> $myVarA und $myVarB in myTest brauchst, �bergib sie
>> lieber als Parameter.
>
> package myLdap;
> sub connectToLdap ($$$$$) {
> my $_ldapDomain = shift;
> my $_DC = shift;
> my $_port = shift;
> my $_ldapBindUser = shift;
> my $_ldapBindPass = shift;
> [...]
> }
>
> Jetzt will ich ein zuf�lliges Passwort erstellen und ben�tige hierf�r:
>
> @alphanumeric = ('a'..'z', 'A'..'Z', 0..9, '!', '?', '$', '/', '.',
> '.', '-', '+', '=');
> $pwLength = 10;

In der Funktion connectToLdap()? Wieso soll die ein zuf�lliges Passwort
erstellen?


> Ausserdem soll Net::LDAP $retries mal versuchen, sich mit dem Server zu
> connecten:
>
> $retries = 5;

Die Variable w�rde ich aber auf keinen Fall $main::retries nennen, da
sie spezifisch f�r Dein myLdap Modul ist. Wenn schon, dann hei�t sie
$myLdap::retries. Dann kannst Du sie in myLdap mit

our $retries = 5;

definieren und initialisieren und wenn n�tig im main mit

$myLdap::retries = 10;

�berschreiben.


Aber das schreit wirklich nach einem anderen Interface:

package myLdap;

sub connect {
my %opt = @_;
croak "no domain" unless $opt{domain};
$opt{port} //= 389;
$opt{retries} //= 5;
$opt{pwLength} //= 10;
...
}

und dann rufst Du

myLdap::connect(domain => 'example.net', user => 'joe', ...);

auf.

Oder Du machst Dir gleich ein myLdap Objekt. Die Wahrscheinlichkeit,
dass Du mal zwei davon brauchen k�nntest, ist ja nicht so klein ...

hp

Frank Seitz

unread,
Oct 31, 2009, 12:50:55 PM10/31/09
to
Helmut Schneider wrote:
>
> Von den obigen 3 Werten sind aus meiner Sicht mindestens eine konstant
> (@alphanumeric), die m�ssen nicht unbedingt jedesmal einer Subroutine
> �bergeben werden. Das kostet doch auch Ressourcen, oder nicht (Objekt
> �bergeben, Kopie erstellen, Kopie wieder l�schen)?!

Wenn dir die �bergabe zweier skalarer Parameter �ber den Stack
an eine Subroutine Kopfzerbrechen bereitet, weil dies zu viel Aufwand
sein k�nnte, solltest du lieber in Assembler programmieren.

Frank Seitz

unread,
Nov 1, 2009, 6:25:02 AM11/1/09
to
Helmut Schneider wrote:

> Frank Seitz wrote:
>>
>> Daran, dass es hakelig ist, l�sst sich ablesen, dass du ein
>> untaugliches Konzept verfolgst. Wenn du die Variablenwerte
>> $myVarA und $myVarB in myTest brauchst, �bergib sie
>> lieber als Parameter.
>
> Von den obigen 3 Werten sind aus meiner Sicht mindestens eine konstant
> (@alphanumeric), die m�ssen nicht unbedingt jedesmal einer Subroutine
> �bergeben werden. Das kostet doch auch Ressourcen, oder nicht (Objekt
> �bergeben, Kopie erstellen, Kopie wieder l�schen)?!

Untaugliche Konzepte sind oft das Resultat fehlgeleiteter �berlegungen.
So auch hier. Das h�rt sich vielleicht arrogant an, ist auf
den Punkt gebracht aber der eigentliche Kern des Problems.

Gr��e
Frank Seitz

Helmut Schneider

unread,
Nov 2, 2009, 1:20:47 PM11/2/09
to
Peter J. Holzer wrote:

> $opt{port} //= 389;

Was bewirkt "//="?

> Oder Du machst Dir gleich ein myLdap Objekt. Die Wahrscheinlichkeit,
> dass Du mal zwei davon brauchen k�nntest, ist ja nicht so klein ...

Macht vermutlich Sinn, ja.

Paolo Peruzzi

unread,
Nov 3, 2009, 3:01:26 AM11/3/09
to
Am Montag, den 02.11.2009, 18:20 +0000 schrieb Helmut Schneider:

> Peter J. Holzer wrote:
> > $opt{port} //= 389;

> Was bewirkt "//="?

Leider sagt [1] darüber nichts. Wie auch += wird es wohl bedeuten:

$opt{port} = $opt{port} // 389;

Wobei // der Defined-Or Operator ist [2] und in diesem Fall den Hash
default-bedatet, wenn er nicht bereits per Übergabe bedatet wurde.

[1] http://perldoc.perl.org/perlop.html
[2] http://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or

Gruß,
Paolo

Paolo Peruzzi

unread,
Nov 3, 2009, 3:18:17 AM11/3/09
to
Am Samstag, den 31.10.2009, 12:30 +0100 schrieb Peter J. Holzer:

> Es ist definitiv eine Ausnahme, dass Du in einem Modul, das mit use

> eingebunden wird, Code hast, der sofort ausgeführt wird und nicht nur


> der Initialisierung dient. Normalerweise werden in Modulen nur
> Funktionen bzw. Methoden definiert und eventuell ein paar Variablen
> initialisiert. Wenn Du Dein myTest.pm so umschreibst:
>
> package myTest;
>
> sub print_vars {
> print "\$myVarA = " . $main::myVarA . "\n";
> print "\$myVarB = " . $main::myVarB . "\n";
> }
>
> 1;
>
> und dann in test.pl
>
> myTest::print_vars()
>

> aufrufst, wird es wie gewünscht funktionieren, weil der Aufruf zu einem


> Zeitpunkt erfolgt, zu dem $main::myVarA und $main::myVarB schon
> initialisiert sind.

Vielen Dank, jetzt verstehe ich, warum dieser Ansatz hier schon lange
funktioniert.

Welcher Ansatz wäre zu wählen, wenn test.pl ein Daemon ist (RPC-Server)
und selbst myTest.pm verwendet? Das Package benötigt verschiedene Daten
bei jedem Funktionsaufruf, die es ausliest oder auch ändert. Diese Daten
halte ich wie hier im "Daemon" test.pl und verwende sie im Package über
Namespace $main::. Ist für diesen Fall der Ansatz vertretbar oder doch
lieber der folgende:

> Wenn $myVarA und $myVarB der Initialisierung von myTest dienen, dann

> ist es vermutlich besser und lesbarer, Du übergibst sie gleich beim use:


>
> use myTest (1, 2);
> oder
> use myTest (myVarA => 1, myVarB => 2);
>
> und verwendest eine import-Routine in myTest.pm und dort package-globale
> Variablen zu setzen.

Wo kann ich dazu mehr lesen? In http://perldoc.perl.org/perlmod.html
habe ich soetwas nicht gefunden.

Gruß,
Paolo

Ferry Bolhar

unread,
Nov 3, 2009, 4:11:59 AM11/3/09
to
"Helmut Schneider":

> Was bewirkt "//="?

Neuer Operator in Perl 5.10. Aus perldelta:

> Defined-or operator
>
> A new operator "//" (defined-or) has been implemented. The following
> expression:
>
> $a // $b
>
> is merely equivalent to
>
> defined $a ? $a : $b
>
> and the statement
>
> $c //= $d;
>
> can now be used instead of
>
> $c = $d unless defined $c;
>
> The "//" operator has the same precedence and associativity as "||".
> Special care has been taken to ensure that this operator Do What You
> Mean while not breaking old code, but some edge cases involving the
> empty regular expression may now parse differently. See perlop for
> details.

LG, Ferry

--
Ing. Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: ferdinand.bolh...@wien.gv.at


Helmut Schneider

unread,
Nov 3, 2009, 5:40:06 AM11/3/09
to
Ferry Bolhar wrote:

> "Helmut Schneider":
>
> > Was bewirkt "//="?
>
> Neuer Operator in Perl 5.10. Aus perldelta:
>
> > Defined-or operator
> >
> > A new operator "//" (defined-or) has been implemented. The
> > following expression:
> >
> > $a // $b
> >
> > is merely equivalent to
> >
> > defined $a ? $a : $b
> >
> > and the statement
> >
> > $c //= $d;
> >
> > can now be used instead of
> >
> > $c = $d unless defined $c;

Praktisch. "unless" sollte ich mir auch angew�hnen.

Merci, Helmut

Helmut Wollmersdorfer

unread,
Nov 3, 2009, 6:04:10 AM11/3/09
to
Helmut Schneider wrote:
> Ferry Bolhar wrote:

>>> $c = $d unless defined $c;
>
> Praktisch. "unless" sollte ich mir auch angew�hnen.

Nachgestellte Bedingungen sind in den Augen mancher Puristen aber
schlechter Programmierstil.

Helmut Wollmersdorfer

Helmut Schneider

unread,
Nov 3, 2009, 6:32:16 AM11/3/09
to
Helmut Wollmersdorfer wrote:

Hurra, noch ein Minenfeld. ;) Aber die "Gefahr" ist hier nicht gegeben,
ich hab die Bedingung so oder so gerne vorne stehen zwecks der
�bersichtlichkeit. "unless" l�sst beim �berfliegen besser zwischen "if"
und "if not" unterscheiden.

Aber Danke f�r die Warnung. :)

Peter J. Holzer

unread,
Nov 3, 2009, 5:51:32 PM11/3/09
to

Perl ist in den Augen mancher Puristen schlechter Programmierstil.

SCNR,
hp

Peter J. Holzer

unread,
Nov 7, 2009, 4:02:47 AM11/7/09
to
On 2009-11-03 08:18, Paolo Peruzzi <pa...@public-files.de> wrote:
> Am Samstag, den 31.10.2009, 12:30 +0100 schrieb Peter J. Holzer:
>> Es ist definitiv eine Ausnahme, dass Du in einem Modul, das mit use
>> eingebunden wird, Code hast, der sofort ausgef锟絟rt wird und nicht nur

>> der Initialisierung dient. Normalerweise werden in Modulen nur
>> Funktionen bzw. Methoden definiert und eventuell ein paar Variablen
>> initialisiert.
[...]

> Vielen Dank, jetzt verstehe ich, warum dieser Ansatz hier schon lange
> funktioniert.
>
> Welcher Ansatz w锟絩e zu w锟絟len, wenn test.pl ein Daemon ist (RPC-Server)
> und selbst myTest.pm verwendet?

Warum sollte das einen Unterschied machen?

> Das Package ben锟絫igt verschiedene Daten bei jedem Funktionsaufruf, die
> es ausliest oder auch 锟絥dert. Diese Daten halte ich wie hier im
> "Daemon" test.pl und verwende sie im Package 锟絙er Namespace $main::.

Warum h锟絣tst Du sie im Namespace main::, wenn sie das Package ben锟絫igt?
Es ist doch viel einfacher und lesbarer, sie im Namespace des Packages
zu halten.

> Ist f锟絩 diesen Fall der Ansatz vertretbar oder doch


> lieber der folgende:
>
>> Wenn $myVarA und $myVarB der Initialisierung von myTest dienen, dann

>> ist es vermutlich besser und lesbarer, Du 锟絙ergibst sie gleich beim use:


>>
>> use myTest (1, 2);
>> oder
>> use myTest (myVarA => 1, myVarB => 2);
>>
>> und verwendest eine import-Routine in myTest.pm und dort package-globale
>> Variablen zu setzen.
>
> Wo kann ich dazu mehr lesen? In http://perldoc.perl.org/perlmod.html
> habe ich soetwas nicht gefunden.

Dort steht nur lapidar, dass (und wie) use die import-Routine des Moduls
aufruft. Was man dann damit anfangen kann, ist offenbar der Fantasie des
Lesers 锟絙erlassen. Hier ein kleines Beispiel:


package MyTest;

my $var1 = 23;
my $var2 = 17;

sub import {
my ($package, %options) = @_;
if (defined $options{param1}) {
$var1 = $options{param1};
}
if (defined $options{param2}) {
$var2 = $options{param2};
}
}

sub printvars {
print "var1 = $var1; var2 = $var2\n";
}
1;
__END__


#!/usr/bin/perl
use warnings;
use strict;

use MyTest;

MyTest->printvars();
__END__

#!/usr/bin/perl
use warnings;
use strict;

use MyTest param1 => 'foo', param2 => 4711;

MyTest->printvars();
__END__


Hier habe die Variablen $var1 und $var2 sogar lexikalisch definiert,
d.h., sie sind au锟絜rhalb ihres Scopes gar nicht erreichbar, man kann
also nicht mit $MyTest::var1 darauf zugreifen. Sollte auch nicht
notwendig sein.

hp

Paolo Peruzzi

unread,
Nov 9, 2009, 2:48:58 AM11/9/09
to
Am Samstag, den 07.11.2009, 10:02 +0100 schrieb Peter J. Holzer:

> > Das Package benötigt verschiedene Daten bei jedem Funktionsaufruf, die
> > es ausliest oder auch ändert. Diese Daten halte ich wie hier im
> > "Daemon" test.pl und verwende sie im Package über Namespace $main::.

> Warum hältst Du sie im Namespace main::, wenn sie das Package benötigt?


> Es ist doch viel einfacher und lesbarer, sie im Namespace des Packages
> zu halten.

Irgendwie war ich fälschlicherweise der Meinung, die Objekte des
Packages würden nach dem Funktionsaufruf nicht mehr existieren. Ich
verstehe nun, dass das Package nur einen Namensraum beschreibt, der
Definitionen bereithält etc. Code am Anfang wird sogar ausgeführt, nur
wie beim OP leider in der falschen Reihenfolge.

> Dort steht nur lapidar, dass (und wie) use die import-Routine des Moduls
> aufruft. Was man dann damit anfangen kann, ist offenbar der Fantasie des

> Lesers überlassen. Hier ein kleines Beispiel:
> ...

d.h. import() wird durch das use immer implizit aufgerufen? Diese
existiert aber nur, wenn explizit definiert oder geerbt?

Verstehe ich richtig, dass Exporter [1] genau den entgegengesetzten Weg
beschreibt? Wo gibt es denn hierfür sinnvolle Verwendung, wenn entweder
eine Variable nach main:: gehört oder aber besser zum Package, aber
nicht im Package definiert und trotzdem außerhalb verwendet wird.
Man würde sich auch nur das Tippen des Namensraums sparen, wenn bei
nicht lexikalisch (my) definierten Variablen immer auch über Package::
zugegriffen werden kann?

Gruß,
Paolo

[1] http://perldoc.perl.org/Exporter.html

Peter J. Holzer

unread,
Nov 10, 2009, 11:25:30 AM11/10/09
to
On 2009-11-09 07:48, Paolo Peruzzi <pa...@public-files.de> wrote:
> Am Samstag, den 07.11.2009, 10:02 +0100 schrieb Peter J. Holzer:
>> > Das Package ben�tigt verschiedene Daten bei jedem Funktionsaufruf, die
>> > es ausliest oder auch �ndert. Diese Daten halte ich wie hier im
>> > "Daemon" test.pl und verwende sie im Package �ber Namespace $main::.
>
>> Warum h�ltst Du sie im Namespace main::, wenn sie das Package ben�tigt?

>> Es ist doch viel einfacher und lesbarer, sie im Namespace des Packages
>> zu halten.
>
> Irgendwie war ich f�lschlicherweise der Meinung, die Objekte des
> Packages w�rden nach dem Funktionsaufruf nicht mehr existieren. Ich

> verstehe nun, dass das Package nur einen Namensraum beschreibt, der
> Definitionen bereith�lt etc. Code am Anfang wird sogar ausgef�hrt, nur

> wie beim OP leider in der falschen Reihenfolge.

Ob das die falsche oder richtige Reihenfolge ist, h�ngt nat�rlich von
der Intention ab. Sie werden unmittelbar nachdem das Modul kompiliert
wurde, ausgef�hrt, was ich zumindest f�r unmittelbar einsichtig halte
(wann sollte das sonst passieren?).


>> Dort steht nur lapidar, dass (und wie) use die import-Routine des Moduls
>> aufruft. Was man dann damit anfangen kann, ist offenbar der Fantasie des

>> Lesers �berlassen. Hier ein kleines Beispiel:


>> ...
>
> d.h. import() wird durch das use immer implizit aufgerufen? Diese
> existiert aber nur, wenn explizit definiert oder geerbt?

Ja.


> Verstehe ich richtig, dass Exporter [1] genau den entgegengesetzten Weg
> beschreibt?

Jein. Der Aufruf der von Exporter zur Verf�gung gestellten
import-Routine erfolgt genau gleich. Die tut dann nur was anderes als
die, die ich skizziert habe. W�hrend meine ihre Parameter als
Key/Value-Paare interpretiert und damit lokale Variablen initialisiert,
interpretiert Exporter::import ihre Variablen als Namen lokaler
Variablen bzw. Subroutinen, die es exportieren, d.h., im aufrufenden
Namensraum (das muss nicht main sein!) installieren soll.

Wenn also in package A ein
use B '$var', 'func';
vorkommt und B von Exporter erbt, dann ist nach diesem Statement
$A::var ein Alias von $B::var und &A::func ein Alias von &B::func.


> Wo gibt es denn hierf�r sinnvolle Verwendung, wenn entweder
> eine Variable nach main:: geh�rt oder aber besser zum Package, aber
> nicht im Package definiert und trotzdem au�erhalb verwendet wird.
> Man w�rde sich auch nur das Tippen des Namensraums sparen, wenn bei
> nicht lexikalisch (my) definierten Variablen immer auch �ber Package::
> zugegriffen werden kann?

Im wesentlichen ja. Aber Tipparbeit ersparen ist schon eine sinnvolle
Verwendung. Ein Programm wird nicht unbedingt lesbarer, wenn man dauernd
Math::Trig::sin() statt sin() tippen muss (ok, schlechtes Beispiel, weil
sin() eh builtin ist, aber ich glaube, es illustriert das Argument).

hp

Ferry Bolhar

unread,
Nov 12, 2009, 5:15:52 AM11/12/09
to
"Peter J. Holzer":

>> d.h. import() wird durch das use immer implizit aufgerufen? Diese
>> existiert aber nur, wenn explizit definiert oder geerbt?
>
> Ja.

Sicher? Wurde das mal ge�ndert? Zumindest in einer fr�heren 5.8. Release,
bei der ich das mal getestet habe, wurde import() nur aufgerufen, wenn es
in der betreffenden Klasse vorhanden war, es wurde aber nicht vererbt.

Peter J. Holzer

unread,
Nov 14, 2009, 3:54:16 AM11/14/09
to
On 2009-11-12 10:15, Ferry Bolhar <b...@adv.magwien.gv.at> wrote:
> "Peter J. Holzer":
>>> d.h. import() wird durch das use immer implizit aufgerufen? Diese
>>> existiert aber nur, wenn explizit definiert oder geerbt?
>>
>> Ja.
>
> Sicher? Wurde das mal ge锟絥dert?

Jetzt machst Du mich unsicher ;-). Aber ja, ich bin mir sicher. Sonst
k锟絥nte der Exporter n锟絤lich nicht funktionieren: Das Package das etwas
exportieren m锟絚hte, definiert ja selbst keine import-Routine sondern
erbt sie nur vom Exporter.


> Zumindest in einer fr锟絟eren 5.8. Release,


> bei der ich das mal getestet habe, wurde import() nur aufgerufen, wenn es
> in der betreffenden Klasse vorhanden war, es wurde aber nicht vererbt.

Kann ich mir nicht vorstellen, da h锟絫te mindestens halb CPAN nicht mehr
funktioniert.

Kleiner Test:

109% /usr/bin/perl -v

This is perl, version 5.005_03 built for i386-linux

Copyright 1987-1999, Larry Wall
...

110% cat Parent.pm
package Parent;

sub import {
print __PACKAGE__, "::import called:\n";
print "\t$_\n" for (@_);
}

1;

111% cat Child.pm
package Child;
use Parent;

@ISA = qw(Parent);

1;

112% cat test_import
#!/usr/bin/perl
use strict;

use Child qw(foo bar baz);

print "hallo\n";


113% ./test_import
Parent::import called:
Parent
Parent::import called:
Child
foo
bar
baz
hallo

锟絣tere Version von perl habe ich keine mehr ...

hp

0 new messages