Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]5612[/thread]

problem mit lexikalischen variablen

Leser: 2


<< |< 1 2 >| >> 18 Einträge, 2 Seiten
kabel
 2003-08-06 01:23
#59552 #59552
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
folgender code behauptet, der hash sei leer:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
my %tags = (
a => \&anchor_handler,
img => \&image_handler,
frame => \&frame_handler,
);

sub dispatcher {
my ($self, $attributes, $tagname) = @_;
if (exists $tags{$tagname}) {
$tags{$tagname}->($self, $attributes);
}
}
}

was offensichtlich falsch ist. $tagname ist immer richtig initialisiert durch den HTML::Parser. die drei subroutinen werden direkt drunter implementiert; daran liegts net, hab die gerade mal hochgezogen, gleiches verhalten. das ist die einzige stelle, an der tags als variablenname vorkommt.

strict ist aktiv, sonst müsste er ja über die nicht-deklaration des hashes meckern, aber warum wird der nicht initialisert, so wie ich das will?!

folgendes funktioniert:
Quote
kabel@linux:~/progs/perl> perl
{
my %a = 1 .. 4;
sub print_a { foreach (keys %a) { print $_ . " => " . $a{$_} . "\n";}}
}

print_a ();
1 => 2
3 => 4
kabel@linux:~/progs/perl>


ich kann mir keinen reim darauf machen. übersehe ich etwas offensichtliches? ???
-- stefan
esskar
 2003-08-06 01:44
#59553 #59553
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
ich glaube $tags existiert zwar, ist aber wegen
den { } um die my %tags und sub dispatcher nicht mehr wirklich valide, wenn dispatcher aufgerufen wird...
entfern mal die klammern, bzw. zieh %tags in dipatcher rein, wenn du es sonst nid brauchst!
pq
 2003-08-06 01:48
#59554 #59554
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
hmm...
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ perl -wle'
{
  my %tags = (
      a       => \&anchor_handler,
  );
                                 
  sub dispatcher {
      my ($self, $attributes, $tagname) = @_;
      if (exists $tags{$tagname}) {
          $tags{$tagname}->($self, $attributes);
      }                                        
  }                                            
}      
sub anchor_handler { print "sub anchor_handler(@_)" }
dispatcher("self","attr","a");'
sub anchor_handler(self attr)
$

klappt doch...
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
pq
 2003-08-06 01:50
#59555 #59555
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=esskar,05. 08 2003,23:44]ich glaube $tags existiert zwar, ist aber wegen
den { } um die my %tags und sub dispatcher nicht mehr wirklich valide, wenn dispatcher aufgerufen wird...[/quote]
doch, das ist korrekter code, denn da dispatcher() in einer closure
definiert ist, bleibt %tags gültig.
closures werden in, äh, perlsub oder perlsyn behandelt,
glaube ich.

edit: typo\n\n

<!--EDIT|pq|1060120284-->
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
kabel
 2003-08-06 12:22
#59556 #59556
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
am typ der variable liegt es nicht, wenn ich %tags global deklariere mittels our, bleibt das fehlverhalten bestehen.

das skript ist ein link-checker, den ich ein bisschen aufbohren will (graphenausgabe mittels GraphViz, DB etc.) - und damit ich perl endlich mal für was sinnvolles benutze :p

es liegt an der position des hashes. ich habe eine subroutine check_link (). wenn ich den hash vor dieser deklariere, dann funktioniert das ganze. hinterher nicht mehr?! diese subroutine hat mit %tags gar nix zu tun - aber offensichtlich doch ???. die referenz auf die dispatcher-subroutine gebe ich dem parser ganz am anfang, daran kanns auch net liegen... es wird auch keine kopie der subroutine angelegt, denn der dispatcher hat zugriff auf den so deklarierten %tags hash, und muss somit im package main aufgerufen werden. das ist seltsam. ich werde das skript noch ein bisschen verschönern (momentan ein ziemliches gehacke ^_^ ) und dann mal posten.

in welchem dokument war noch mal erklärt, wie perl source genau ausgeführt wird? "app" wars nicht, da hätte ich das noch am ehesten erwartet...
-- stefan
pq
 2003-08-06 14:26
#59557 #59557
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
sorry, kabel, aber kannst du in Perl reden anstatt auf deutsch?
der code, den du oben gepostet hast, tut, was er soll, finde ich, aber dazu
hast du ja keinen kommentar abgegeben.
und was du jetzt mit obiger antwort meinst, kann man nur
spekulieren, also füg doch mal den richtigen code hinzu.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
kabel
 2003-08-06 15:05
#59558 #59558
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
SCNR; wenn du was net versteht, frag nochmal :)

$self->tidy ("code") = "done";
$self->accept ("proposal") and $self->set_mood ("thankful");

read-more 8)

$reader->interchange ($tags_definition, $call_to->("check_link"));
if (before ($tags_definition, $call_to->("check_link"))) {
$script->works ("no");
} else {
$script->works ("yes");
}

$reader->notice (what => both_cases, $dispatcher_sub_definition->is_closure (relative_to => $tags_definition));\n\n

<!--EDIT|kabel|1060178547-->
-- stefan
pq
 2003-08-06 18:18
#59559 #59559
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=kabel,06. 08 2003,16:01]ich hatte doch gerade tatsächlich gedacht, dieses my wird zur compile-zeit ausgeführt, da es konstant ist[/quote]
das my() wird auch zur compile-zeit "ausgeführt" -
zumindest die deklaration wird dem compiler
mitgeteilt.
die zuweisung selbst passiert erst später.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
kabel
 2003-08-06 19:22
#59560 #59560
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
nein, der compiler kennt %tags zu diesem zeitpunkt gar nicht.

Quote
kabel@linux:~/progs/perl> cat pad_test.pl
use strict;
use PadWalker qw/ peek_my /;

print_hiho ();
my $a = "hohi";
my $lex_vars = peek_my (0);
print "der hash hiho existiert ";
unless (exists ($lex_vars->{'%hiho'})) {
print "nicht!";
}
print "!\n";
print "\$a existiert aber\n" if exists $lex_vars->{'$a'};


my %hiho = 1 .. 6;


sub print_hiho {
while (my ($key, $value) = each %hiho) {
print "$key -> $value\n";
}
}
kabel@linux:~/progs/perl> perl -w pad_test.pl
der hash hiho existiert nicht!!
$a existiert aber
kabel@linux:~/progs/perl>


strict meckert nicht, da %tags ja mit my deklariert ist, ABER strict geht anscheinend nur mal quer drüber und teilt dem compiler NICHT mit, dass da lexikalische variablen existieren - sonst müsste er im beispiel den hash finden - tut er aber nicht!

Quote
kabel@linux:~/progs/perl> perl
use strict;
my $hiho if 0;
$hiho = "hallo!";

print "$hiho\n";
hallo!
kabel@linux:~/progs/perl>

strict arbeitet anscheinend auf source-code ebene ... um da näheres zu erfahren, müsste einer eine ebene in die perl source reingehen :graus: ;)
-- stefan
pq
 2003-08-06 15:21
#59561 #59561
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=kabel,06. 08 2003,13:05]if (before ($tags_definition, $call_to->("check_link"))) {
  $script->works ("no");
} else {
  $script->works ("yes");
}[/quote]
ich weiss nicht, wo dein problem sein soll.
wenn du eine subroutine aufrufst, bevor %tags deklariert
wurde, und diese subroutine %tags braucht, dann kann
das doch nicht gehn...
also ruf die subroutine erst hinterher auf.

ansonsten meinte ich mit code posten einen kleinen
ausschnitt, der das problem reproduziert.
Quote
$reader->notice (what => both_cases, $dispatcher_sub_definition->is_closure (relative_to => $tags_definition));

häh?
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< |< 1 2 >| >> 18 Einträge, 2 Seiten



View all threads created 2003-08-06 01:23.