Thread Variablen in Sub's - strict meckert rum. (20 answers)
Opened by popcorn5 at 2007-04-26 20:29

sid burn
 2007-04-27 23:42
#76299 #76299
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=PerlProfi,27.April.2007, 21:23]Ich dachte eigentlich, dass bei jedem Aufruf einer Subroutine, die selbst anon. Subroutinen enthällt, diese auch kompiliert werden müssen, die Variable wird ja jedesmal neu zugeordnet, oder nicht ?[/quote]
Kommt auf den Geltungsbereich der Variable drauf an ob sie neu Kompiliert wird oder nicht. Ansonsten unterscheidet sich eine Anonyme Subroutine nicht sehr stark von einer normalen Subroutine.

Wenn du eine Subroutine anlegst dann wird ein Eintrag in der Symboltabelle erzeugt. In der Symboltabelle existiert ein Typeglob. Ein Typeglob wiederrum ist nichts anderes als ein Perl Hash. Und dieser Perl HASH hat Keys. Und ein spezieller Key zeigt auf die Subroutine.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/perl
use strict;
use warnings;

sub hallo {
print "Hallo, Welt!\n";
}

my $blub = *hallo{CODE};
$blub->();


Der KEY für den Subroutinen Teil heißt CODE. Daher wenn du eine Subroutine erzeugt hast, kannst du aus den Typeglob einfach den Key CODE nehmen, dieser enthält eine Referenz auf die Subroutine. Und dieser kannst nach belieben einer neuen variable zuweisen.

Naja, und wenn du es so siehst. Wo ist da noch der Unterschied wenn du eine Anonyme Subroutine hast?

Eine Annonyme Subroutine ist nichts anderes als eine Referenz auf einen Code Stück. Das ist genau das was bei Perl die Symboltabelle ist.

Ansonsten wenn du eine Anonyme Subroutine in einer Funktion erzeugst dann muss diese Subroutine sicherlich erstmal zur Laufzeit neu Kompiliert werden. Klar in dem Punkt hast du recht. Wenn das ganze aber fertig ist, und du gibst dann eine Referenz in deiner Funktion zurück, dann wird die erstellte Subroutine ja nicht vernichtet. Du hast dann eine fertige Subroutine die aber nicht bei jedem Aufruf neu Kompiliert wird.

Ansonsten um 100%ig Korrekt zu sein, wird die Subroutine auch nicht wirklich komplett zur Laufzeit Kompiliert. Das passiert nur bei einem String eval. Wenn du allerdiengs eine Anonyme Subroutine schreibst und das Ergebnis einen Typeglob zuweist dann passiert die Kompilation trotzdem zur Kompilierzeit, aber die Zuweisung wie du die Funktion ansprichst wird einmalig erst zur Laufzeit festgelegt.

Oder es wird erst zur Laufzeit festgelegt welche Variablen du nutzt.

Beim ersten mal entsteht also sicherlich zur Laufzeit einen Overhead, aber nur beim ersten Aufruf, bzw erzeugen. Danach niht mehr. Komplett Kompilieren zur Laufzeit macht man nur mit einem String eval().

Ansonsten wenn du eine Referenz auf eine erstellte Subroutine zurück gibst dann lebt diese ja beim Verlassen der Subroutine weiterr weil da immer noch eine Referenz drauf zeigt. Ist letztendlich das selbe als wenn du in einer Subroutine eine Datenstruktur erzeugst und dann eine Referenz auf diese Datenstruktur zurück gibst. Diese überlebt dann auch noch weiter, und wird erst dann Zerstört wenn der Refrenzcounter auf 0 geht.

Solange also deine Variable lebt und da etwas auf den Code zeigt wird deine Subroutine nicht zerstört und auch nicht ewig neu Kompiliert.

Auser natürlich deine variable verlässt den Gültigkeitsbereich, und du rufst die Subroutine neu auf die dir dann wieder die Subroutine erstellt.



Nützlich ist das ganze wie bereits gesagt für Closures. Z.B in der OOP kannst du das auch gebrauchen um z.B. Klassenmethoden zu erzeugen die ihre Werte Speichern, aber ohne das package Variablen benutzt werden die Öffentlich zugänglich sind.

Oder du kannst Funktionen damit erzeugen die bei jedem Aufruf etwas anderes zurück geben. So wie es rand() z.B. macht. Ist ja alles letztendlich nichts anderes als eine Closure. ;)\n\n

<!--EDIT|sid burn|1177703781-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread Variablen in Sub's - strict meckert rum.