undefined subroutine
am 16.02.2007 16:03:38 von Frank Kulow
Hallo NG,
im Anhang ein kleines Beispielprojekt, Aufruf perl a.pl.
Ich hätte gern die Zeile "package main;" in c.pm weggelassen.
Wie ist das möglich? (ohne main::subb(); schreiben zu müssen)
Danke Frank
------------------------
#a.pl
use b1;
use c;
c::subc();
#end a.pl
-------------------
#b1.pm
sub subb
{
print 'subb';
}
1;
#end b1.pm
--------------------
#c.pm
package c;
sub subc
{
print 'subc';
package main;
subb();
}
1;
#end c.pm
--------------------
Re: undefined subroutine
am 16.02.2007 19:28:10 von Frank Seitz
Frank Kulow wrote:
> im Anhang ein kleines Beispielprojekt, Aufruf perl a.pl.
>
> Ich hätte gern die Zeile "package main;" in c.pm weggelassen.
>
> Wie ist das möglich? (ohne main::subb(); schreiben zu müssen)
Durch Glob-Aliasing, z.B. via Exporter.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: undefined subroutine
am 19.02.2007 10:16:54 von Ferry Bolhar
Frank Kulow:
> Ich hätte gern die Zeile "package main;" in c.pm weggelassen.
> #b1.pm
> sub subb
> {
> print 'subb';
> }
*main::subb = \&subb;
> 1;
> #end b1.pm
LG, Ferry
--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at
Re: undefined subroutine
am 19.02.2007 12:36:59 von Frank Seitz
Ferry Bolhar wrote:
> Frank Kulow:
>>
>>Ich hätte gern die Zeile "package main;" in c.pm weggelassen.
>>
>>#b1.pm
>>sub subb
>>{
>> print 'subb';
>>}
> *main::subb = \&subb;
>>1;
>>#end b1.pm
Das fügt dem Programm nichts Neues hinzu.
Er müsste in c.pm das Umgekehrte vereinbaren.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: undefined subroutine
am 19.02.2007 14:48:40 von Ferry Bolhar
Frank Seitz:
> Das fügt dem Programm nichts Neues hinzu.
> Er müsste in c.pm das Umgekehrte vereinbaren.
Sorry, du hast natürlich recht. Also in b1.pm
*c::subb = \&subb;
LG, Ferry
--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at
Re: undefined subroutine
am 19.02.2007 15:03:24 von Frank Seitz
Ferry Bolhar wrote:
> Frank Seitz:
>>
>>Das fügt dem Programm nichts Neues hinzu.
>>Er müsste in c.pm das Umgekehrte vereinbaren.
>
> Sorry, du hast natürlich recht. Also in b1.pm
>
> *c::subb = \&subb;
So geht es natürlich auch, ist aber von der
Systematik her schlecht. Besser ist es, wenn der
Alias dort vereinbart wird, wo er benötigt wird.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: undefined subroutine
am 21.02.2007 17:33:27 von Frank Kulow
Hallo NG,
>Ferry Bolhar schrieb:
>
> *c::subb = \&subb;
>
Geht das auch für alle subs, ohne sie persönlich zu benennen?
Den Exporter habe ich nicht verstanden, kann jemand helfen?
in b1.pm ergänzen:
-------
use Exporter;
@EXPORT = qw( subb);
----------
und in c.pm:
----------
use b1;
---------
hilft nicht.
Viele Grüße und Danke
Frank
Re: undefined subroutine
am 22.02.2007 11:21:46 von Ferry Bolhar
Frank Kulow:
>> *c::subb = \&subb;
>
> Geht das auch für alle subs, ohne sie persönlich zu benennen?
Es geht für alle subs, aber nicht automatisch (falls du das
gemeint hast):
Schau dir den Abschnitt "Symbol Tables" in perlmod näher an,
da ist das kurz beschrieben.
Ich arbeite gerade an einem pod-Dokument "perlglobtut"
(a tutortial about symbol tables and typeglobs), da ist das
genau beschrieben und auch die Arbeitsweise des Exporters.
Ich hoffe, dass es rechtzeitig für Perl 5.10 fertig wird.
Ganz kurz:
Ist eine Subroutine "func" in einem Package "B" definiert, so
kann man sie mittels
*A::func = *B::func; oder
*A::func = \&B::func;
auch im Package A abbilden, dh., sie kann dann von dort
genauso mit "func(...);" wie im Package B aufgerufen werden.
Der Exporter tut im Prinzip mit den in @EXPORT bzw.
@EXPORT_OK aufgelisteten Namen genau dasselbe. Diese
Technik bezeichnet man auch als "Aliasing", dh., man macht
&A::func zu einem Alias auf &B::func.
Der Unterschied zwischen den beiden Befehlen ist, dass im
ersten Fall _alles_ von B nach A abgebildet wird, dh., auch
$A::func, @A::func und %A::func entsprechen den jeweiligen
Variablen im Package B ("globales Aliasing"). Im zweiten Fall
wird hingegen nur ein Alias für die Funktion "func()" angelegt,
die Variablen $A::func und $B::func bleiben zwei getrennte,
voneinander unabhängige Variable ("partielles Aliasing").
Letzteres wird auch vom Exporter verwendet.
> use Exporter;
> @EXPORT = qw( subb);
>
> hilft nicht.
Kein Wunder. Im obigen Code fehlt:
@ISA = qw(Exporter); # <--- zum Erben von import()
d.h., die import() Methode des Exporters, die für das
Aliasing zuständig ist, wird von deinem Code gar nicht
aufgerufen.
-> Siehe auch perlobj, perltoot, da ist das Vererbungs-
konzept mittels @ISA genau beschrieben.
LG, Ferry
--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at
Re: undefined subroutine
am 22.02.2007 11:50:50 von Frank Seitz
Ferry Bolhar wrote:
> Ist eine Subroutine "func" in einem Package "B" definiert, so
> kann man sie mittels
>
> *A::func = *B::func; oder
> *A::func = \&B::func;
>
> auch im Package A abbilden
Das ist der allgemeinste Fall. In der Praxis sieht es
IMO am sinnvollsten so aus:
package B;
sub func { ... }
package A;
*func = \&B::func;
Aliasing ist u.a. ein enorm leistungsfähiges Mittel um
ohne Vererbung Methoden zwischen Klassen zu sharen.
Ich persönlich benutze Exporter überhaupt nicht,
weil ich die Nutzung zu umständlich finde.
Aber Vorsicht: Glob-Aliase kann man hinschreiben wie
man möchte, etwaige Schreibfehler auf der rechten Seite
bemerkt man frühestens zur Laufzeit, da Perl (aus
gutem Grund) dort alles akzeptiert.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel