Tobi's Blog

Archiv für die 'Perl::Kinky' Kategorie

Alles zum Thema *Würg*

Die magische Symboltabelle oder: wie autovivication einen in den Wahnsinn treiben kann

Erstellt von Tobi am 15. November 2007

Das die Symboltabelle, in der alle klassenspezifischen Dinge gespeichert werden, nur ein Hash ist war mir ja klar. Das allerdings auch dort autovivication für Methodenaufrufe gilt, nicht.

Folgendes ist passiert: ich habe per can() das vorhandensein einer Methode abgeprüft und musste mit Erschrecken feststellen, das ab diesem Moment der Eintrag ‘can’ in der Symboltabelle der Klasse vorhanden war. Das funktioniert nur mit Klassen, die in einer eigenen Datei liegen. Mit inline-Klassen geht es nicht. Nachvollziebar ist es mit folgendem Code:


use Data::Dumper();
my $handler_class = 'Data::Dumper';
my %before;
my %after;
@before{ keys(%{$handler_class . '::'}) } = (1) x scalar(keys(%{$handler_class . '::'}));
my $sub = $handler_class->can('notExisting');
eval("*$handler_class\::createdAtRuntime = sub { print 1 };");
@after{ keys(%{$handler_class . '::'}) } = (1) x scalar(keys(%{$handler_class . '::'}));
foreach my $key (keys(%after), keys(%before)) {
next if($after{$key} eq $before{$key});
print "$key: before($before{$key}) <> after ($after{$key}) : sub = ".*{$handler_class.'::'.$key}{CODE}."\n";
delete($after{$key});
delete($before{$key});
}

Der Wert der neuen Symboltabellen-Einträge ist leer. Immerhin etwas. Aber schräg ist es schon.

PS: Das war das erste mal, dass ich die komische Syntax zur Mehrfachzuweisung von Hash-keys halbwegs sinnvoll verwenden konnte. Das hat fast schon einen eigenen Eintrag verdient. Oder gibt es jemanden, der im obigen Codebeispiel die @before{… Zeile verständlich findet?

PPS @MKops: Perl rockt! :)

Abgelegt unter Perl::Kinky | 4 Kommentare »

Die dunkle Seite von $/

Erstellt von Tobi am 2. Oktober 2007

Die Variable $/ ist eigentlich allgemein bekannt. Auch die Doku ist übersichtlich. Normalerweise enthält sie den Zeilentrenner für Einleseoperationen.

Unbekannt und auch nicht dokumentiert (in der POD) ist allerdings das Verhalten, wenn man diese Variable auf eine INT-Referenz setzt. Dann wird nämlich nicht an dem Zeichen getrennt sondern nach n-Bytes (Vorsicht bei UTF-8 Daten, da ein Zeichen dort 2 Bytes lang sein kann!!)

Bsp:
$/ = \2;
while(<DATA>) {
print "\nLine: $_";
}
__DATA__
1234567890

Dieser Code ergibt folgende Ausgabe:

Line: 12
Line: 34
Line: 56
Line: 78
Line: 90

Wer weiß, wozu dieses Wissen mal gut ist :?

PS: darauf aufmerksam bin ich durch einen PerlMonks.org Beitrag geworden, wo genau das Verhalten beschrieben wurde.

Abgelegt unter Perl::Kinky | 1 Kommentar »

Sonderstatus von import() / CORE-Funktionen überschreiben

Erstellt von Tobi am 19. August 2007

Wenn man global eine Perl-Interne Funktion überschreiben will, z.B. caller(), kann man nicht direkt *CORE::caller{‘CODE’}, bzw CORE::GLOBAL::caller, einfach neu definieren. Es gibt Perl-Intern einen Schutzmechanismus, der das überschreiben dieser Funktiionen ausschließlich in import()-Funktionen erlaubt.

In Modul ClassA::import() steht der Code, der caller überschreibt.
package ClassA;
sub import {
*CORE::GLOBAL::caller = sub { return 1 };
}

In Modul ClassB muss jetzt ClassA so aufgerufen werden, dass import() verwendet wird:
package ClassB;
use ClassA('*');
print caller();

Und siehe da, es wird ’1′ ausgegeben. Wenn die Klasse mit z.B. use ClassB() eingebunden wird, und man import direkt im code aufruft, geht es nicht.
package ClassB;
use ClassA();
ClassA::import('*');
print caller();

Die caller() Funktion wird hierbei nicht überschrieben.

Hinweis: die import() Methode, die ja eigentlich ein historischer Unfall ist, scheint mehr Sonderstati zu besitzen. Ein aufruf von use strict in jeglicher import() Methode bewirkt, dass sich das auf das aufrufende Package auswirkt. Das kann fatale nebenwirkungen haben, z.B. bei no strict

Abgelegt unter Perl, Perl::Kinky | Keine Kommentare »

Netter Perldoc Fund

Erstellt von Tobi am 19. August 2007

Was schickes für die Kinky-Ecke:

require has special additional dark magic: if you invoke your require replacement as require Foo::Bar, it will actually receive the argument “Foo/Bar.pm” in @_. See “require” in perlfunc.

Gefunden in perlsub.pod

Abgelegt unter Perl::Kinky | Keine Kommentare »

Fukurama::Class

Erstellt von Tobi am 22. Juli 2007

Endlich mal Nägel mit Köpfen. Der erste Teil des Modules für bessere OO-Unterstützung in Perl ist fertig und die Doku ebenfalls. Da das Modul noch nicht online ist, ist die Doku hier zu finden (oder in der Navigation ganz unten links)

Abgelegt unter Perl, Perl::Kinky | Keine Kommentare »

 

Switch to our mobile site