Devel::FindRef - Was referenziert diese Variable?

| | Kommentare (0)

Häufig steht man vor der Frage, wo genau eine Variable (oder allgemein ein Perl-Wert) referenziert wird.

Devel::FindRef von Marc Lehmann ist ein kleines Modul, mit dem man exakt herausfinden kann, wo eine bestimmte Variable referenziert wird, ob es einen Referenz-Zyklus gibt, oder welche closure den Wert noch referenziert.

Marc Lehmann hat Devel::FindRef in einem Lightning Talk auf dem 11. Deutschen Perl-Workshop in Frankfurt/Main vorgestellt.

Einfaches Beispiel

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

use Devel::FindRef;
                         
    # Die Variable, die untersucht werden soll
our $var            = 'hi there';

    # Ein paar Referenzen auf diese Variable
my $global_my       = \$var;
our %global_hash    = ( key1 => \$var );
our $global_hashref = { key2 => \$var };


testsub();
                           
sub testsub {             
      my $testsub_local = $global_hashref;
	  print "Track für \$var '$var':\n";
      print Devel::FindRef::track \$var;
}                             

Das Programm erzeugt folgende Ausgabe:

Track für $var 'hi there':
SCALAR(0x8169fe8) [refcount 5] is
+- in the global $main::var.
+- referenced by REF(0x8169fa8) [refcount 1], which is
|  in the lexical '$global_my' in CODE(0x8155318) [refcount 2], which is
|     +- the containing scope for CODE(0x81a5468) [refcount 3], which is
|     |  in the global &main::testsub.
|     +- the main body of the program.
+- referenced by REF(0x8169f28) [refcount 1], which is
|  in the member 'key2' of HASH(0x81550b8) [refcount 2], which is
|     +- referenced by REF(0x81a54c8) [refcount 1], which is
|     |  in the lexical '$testsub_local' in CODE(0x81a5468) [refcount 3], which was seen before.
|     +- referenced by REF(0x81a5168) [refcount 1], which is
|        in the global $main::global_hashref.
+- referenced by REF(0x8155308) [refcount 1], which is
|  in the member 'key1' of HASH(0x816a368) [refcount 1], which is
|     in the global %main::global_hash.
+- referenced by REF(0x81551d8) [refcount 1], which is
   a temporary on the stack.

Die Ausgabe muss man sich anfangs wohl zwei- oder dreimal anschauen, danach wird es besser.

Beispiel: Verwendung von closures und weaken

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


use Devel::FindRef;
use Scalar::Util;
                         
our $var            = 'hi there';
my $global_my       = \$var;
our %global_hash    = ( key1 => \$var);
our $global_hashref = { key2 => \$var };
                           
sub testsub {             
      my $testsub_local = $global_hashref;
	  print "Track fuer \$var '$var':\n";
      print Devel::FindRef::track \$var;
}                             


my $closure = sub {
      my $closure_var = \$_[0];
      Scalar::Util::weaken (my $weak_ref = \$var);
      testsub();
   };

$closure->($var);

Das Programm erzeugt folgende Ausgabe:

Track fuer $var 'hi there':
SCALAR(0x8169f58) [refcount 6] is
+- referenced by REF(0x81a5640) [refcount 1], which is
|  in the lexical '$closure_var' in CODE(0x81a5600) [refcount 4], which is
|     +- the closure created at f2.pl:22.
|     +- referenced by REF(0x81a5440) [refcount 1], which is
|     |  in the lexical '$closure' in CODE(0x8155318) [refcount 2], which is
|     |     +- the containing scope for CODE(0x81a5460) [refcount 3], which is
|     |     |  in the global &main::testsub.
|     |     +- the main body of the program.
|     +- in the lexical '&' in CODE(0x8155318) [refcount 2], which was seen before.
+- referenced by REF(0x816a008) [refcount 1], which is
|  in the lexical '$global_my' in CODE(0x8155318) [refcount 2], which was seen before.
+- in the global $main::var.
+- referenced by REF(0x8169f28) [refcount 1], which is
|  in the member 'key2' of HASH(0x81550b8) [refcount 2], which is
|     +- referenced by REF(0x81a54d0) [refcount 1], which is
|     |  in the lexical '$testsub_local' in CODE(0x81a5460) [refcount 3], which was seen before.
|     +- referenced by REF(0x81a51a0) [refcount 1], which is
|        in the global $main::global_hashref.
+- referenced by REF(0x8155308) [refcount 1], which is
|  in the member 'key1' of HASH(0x816a368) [refcount 1], which is
|     in the global %main::global_hash.
+- referenced by REF(0x81551d8) [refcount 1], which is
   a temporary on the stack.

Cool!

Siehe auch:

Jetzt kommentieren

Über diese Seite

Diese Seite enthält einen einen einzelnen Eintrag von Thomas Fahle vom 2.03.09 15:50.

Perl Gezwitscher - Lesenswerte Twitterfeeds für Perlprogrammierer ist der vorherige Eintrag in diesem Blog.

Talk: Goldene Regeln für die Entwicklung von Perl-Applikationen von Alvar Freude ist der nächste Eintrag in diesem Blog.

Aktuelle Einträge finden Sie auf der Startseite, alle Einträge in den Archiven.

Blog Roll

Powered by

Powered by Movable Type 5.2.10

Creative Commons-Lizenz

Creative Commons License
Dieses Weblog steht unter einer Creative Commons-Lizenz.