Thread Package ruft Funktion aus anderem Package auf? (17 answers)
Opened by BratHering at 2005-11-27 16:12

Dubu
 2005-11-28 01:12
#60445 #60445
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Okay, ich habe das mit dem "." mal ausprobiert, mit und ohne use lib und ganz ohne FindBin (was man vernuenftigerweise sonst immer benutzen sollte).

Ich habe hier ein Skript useModules.pl mit folgendem Inhalt:
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl
use strict;
use warnings;
BEGIN { print "Vorher:\n"; print "»$_«\n" for @INC; }
use lib '.';
BEGIN { print "Nachher:\n"; print "»$_«\n" for @INC; }
use Foo::Bar;

Foo::Bar::output();


Das Modul Foo::Bar liegt in ./Foo/Bar.pm, also ein Verzeichnis unterhalt von useModules.pl. Es benutzt keinen Exporter o.ae., aber den brauche ich ja auch nicht, wenn ich die Funktion qualifiziert aufrufe. So sieht's aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
package Foo::Bar;

use strict;
use warnings;
use Foo::Bar::Baz;

sub output {
   print "Hello, this is " . _ _PACKAGE_ _ . "!\n";
   Foo::Bar::Baz::output2();
}

42;


Das in Foo::Bar benutzte Modul Foo::Bar::Baz wiederum liegt in ./Foo/Bar/Baz.pm und sieht fast identisch aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
package Foo::Bar::Baz;

use strict;
use warnings;

sub output2 {
   print "Hello, this is " . _ _PACKAGE_ _ . "!\n";
}

42;


Wenn ich nun das Programm useModules.pl ausfuehre, kommt folgendes heraus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ ./useModules.pl
Vorher:
»/etc/perl«
»/usr/local/lib/perl/5.8.7«
»/usr/local/share/perl/5.8.7«
»/usr/lib/perl5«
»/usr/share/perl5«
»/usr/lib/perl/5.8«
»/usr/share/perl/5.8«
»/usr/local/lib/site_perl«
»/usr/local/lib/perl/5.8.4«
».«
Nachher:
».«
»/etc/perl«
»/usr/local/lib/perl/5.8.7«
»/usr/local/share/perl/5.8.7«
»/usr/lib/perl5«
»/usr/share/perl5«
»/usr/lib/perl/5.8«
»/usr/share/perl/5.8«
»/usr/local/lib/site_perl«
»/usr/local/lib/perl/5.8.4«
Hello, this is Foo::Bar!
Hello, this is Foo::Bar::Baz!

Funktioniert also. Foo::Bar wird gefunden, und von dort aus Foo::Bar::Baz auch.

Von der Ausgabe her koennte man denken, dass das use lib '.' nur das aktuelle Verzeichnis von ganz hinten in @INC nach ganz vorne nimmt. Ohne use lib '.' sollte es also eigentlich keinen Unterschied machen:
Code: (dl )
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl
use strict;
use warnings;
BEGIN { print "Vorher:\n"; print "»$_«\n" for @INC; }
# use lib '.';
BEGIN { print "Nachher:\n"; print "»$_«\n" for @INC; }
use Foo::Bar;

Foo::Bar::output();


Aber Pustekuchen!
Die Ausgabe sieht jetzt so aus:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ ./useModules.pl
Vorher:
»/etc/perl«
»/usr/local/lib/perl/5.8.7«
»/usr/local/share/perl/5.8.7«
»/usr/lib/perl5«
»/usr/share/perl5«
»/usr/lib/perl/5.8«
»/usr/share/perl/5.8«
»/usr/local/lib/site_perl«
»/usr/local/lib/perl/5.8.4«
».«
Nachher:
»/etc/perl«
»/usr/local/lib/perl/5.8.7«
»/usr/local/share/perl/5.8.7«
»/usr/lib/perl5«
»/usr/share/perl5«
»/usr/lib/perl/5.8«
»/usr/share/perl/5.8«
»/usr/local/lib/site_perl«
»/usr/local/lib/perl/5.8.4«
».«
Undefined subroutine &Foo::Bar::output called at ./useModules.pl line 9.

Man beachte: Die Fehlermeldung kommt nicht vom use Foo::Bar! Das Modul wird also gefunden, aber die Funktion output() darin nicht.

Ich gebe zu, dass ich dieses Verhalten nicht verstehe.

Edit: Das Forum hat zweimal _ _PACKAGE_ _ geschluckt. Bitte (wie ueblich) die Leerzeichen wegdenken / nach paste korrigieren.\n\n

<!--EDIT|Dubu|1133184386-->

View full thread Package ruft Funktion aus anderem Package auf?