Schrift
[thread]8952[/thread]

Variablen in Sub's - strict meckert rum.



<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten
popcorn5
 2007-04-26 20:29
#76283 #76283
User since
2003-09-24
60 Artikel
BenutzerIn
[default_avatar]
hallo,

strict meckert bei variablen in subs rum.

sub test
{
my $var=1;
print $var."\n";
}

Ergibt die Fehlermeldung:

Variable "$var" will not stay shared...

Ich brauche die Variable nach der Sub nicht mehr.
Was mache ich falsch ?

Danke.
Ronnie
 2007-04-26 20:54
#76284 #76284
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Dein Beispiel erzeugt nicht die von dir angegebene Fehlermeldung. Folgendes aber sehr wohl:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

sub foo {

my $var = 'x';

sub test {
$var=1;
print $var."\n";
}

test;
$var = 'y';
}

foo;
test;

use diagnostics; liefert etwas mehr Informationen für die Ursache des Fehlers ;)

EDIT: Beispiel etwas ausgebaut.\n\n

<!--EDIT|Ronnie|1177606564-->
PerlProfi
 2007-04-26 21:02
#76285 #76285
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Das ist nicht strict, sondern warnings das da meckert.
Und wie Ronnie schon gesagt hat gibt dein Beispiel keine Warnung:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl
use strict;
use warnings 'all';

&test;

sub test
{
my $var=1;
print $var."\n";
}


Warscheinlich hast du eine subroutine innerhalb einer subroutine, die dann auf eine Variable der äußeren zugreift, so wie in Ronnies Beispiel:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/perl
use strict;
use warnings 'all';

&test;

sub test
{
my $var = 1;

sub test2
{
print $var."\n";
}

&test2;
}

warnings denkt hier nämlich, du möchtest eine closure definieren und sagt dir, dass das so nicht geht.
Der Wert von $var wird hier nur einmal auf 1 gesetzt und auch wenn er sich in der äußeren ändert hat das keinen Einfluss auf den Wert von $var in der inneren Subroutine.

Vielleicht hast du dich ja nur vertippt, und wenn nicht würde ich dir raten die Variable als Parameter zu übergeben, oder die innere Subroutine als anon. Subroutine zu schreiben damit sie bei Aufruf der äußeren neu interpretiert wird.
Code: (dl )
1
2
3
4
5
6
7
8
# entweder
$test2 = sub { print $var."\n" }
# oder
sub test2
{
my $var = shift;
print $var."\n";
}


Wenn es nicht anders geht, kannst du auch no warnings 'closure'; benutzen um die Warnung in diesem kurzen Bereich abzuschalten.

MfG
popcorn5
 2007-04-26 21:35
#76286 #76286
User since
2003-09-24
60 Artikel
BenutzerIn
[default_avatar]
Hallo,

verzeiht, ich habe es "spartanisch" gepostet.
klar habe ich eine sub in einer sub.
allerdings nicht warnigs mit eingebunden, aber strict. nehme ich strict raus, verschwindet auch die warnung.

mein script müsste vereinfacht eigentlich so aussehen:

Code: (dl )
1
2
3
4
5
6
7
8
9
sub eins
{
my $var=1;
sub zwei
{
print $var."\n";
}
&sub zwei();
}

Danke, habe verstanden warum die warnung auftaucht. Da ich die Var nach der ersten sub nicht mehr brauche ist das ok, wenn ich die warnungen einfach abschalte, es funktioniert ja.\n\n

<!--EDIT|popcorn5|1177608954-->
PerlProfi
 2007-04-27 01:00
#76287 #76287
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Wenn $var wirklich nicht variabel ist, dann schon, ansonsten bekommst du damit später Probleme.

Und es ist wirklich warnings das da meckert, warscheinlich hast du in deiner Shebang ein -w, oder sonst irgendwo den Schalter gesetzt, dann kommt die Warnung natürlich auch, ansonsten bekomme ich bei folgendem keine Warnung:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/perl
use strict;
#use warnings 'all';

&test;

sub test
{
my $var = 1;

sub test2
{
print $var."\n";
}

&test2;
}
\n\n

<!--EDIT|PerlProfi|1177621441-->
Sucher
 2007-04-27 01:41
#76288 #76288
User since
2007-03-26
47 Artikel
BenutzerIn
[default_avatar]
Hallo,

nur aus Interesse: Warum möchte man denn eine sub in einer sub definieren?

Grüße,
GoodFella
 2007-04-27 01:56
#76289 #76289
User since
2007-01-09
192 Artikel
BenutzerIn
[default_avatar]
[quote=Sucher,26.04.2007, 23:41]Hallo,

nur aus Interesse: Warum möchte man denn eine sub in einer sub definieren?

Grüße,[/quote]
Um den Sub-Namespace möglichst klein zu halten und logische Einheiten beeinander zu belassen?
PerlProfi
 2007-04-27 02:06
#76290 #76290
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Zum Modularisieren - Aufteilen eines Problems in kleinere Teileaufgaben.
Der unterste Teil verwendet die nächst höheren Teile um die Aufgabe zu erfüllen, die wiederum auch die nächst höheren Teile benutzen um ihre jeweilige Teilaufgabe zu erfüllen, usw...

In vielen Sprachen ist es auch so, dass die einzelnen Teile auch nur in der nächst höheren Ebene benutzt werden können, d.h. es ist sauberer.
In Perl kann man das auch erreichen, durch anon. Subroutinen.
Alle anderen können im gesamten package benutzt werden.
Oder gibt es da noch einen anderen Weg ?
Ronnie
 2007-04-27 09:20
#76291 #76291
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=Sucher,26.04.2007, 23:41]nur aus Interesse: Warum möchte man denn eine sub in einer sub definieren?[/quote]
Closures! Ein beliebtes Beispiel sind Iteratoren:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

sub create_iter {
my $start = shift || 1;
my $func = shift || sub { $_[0] += 1 };

return sub { my $t = $start; $func->($start); return $t }
}

my $iter = create_iter(17, sub { $_[0] += 2 });

while (my $i = $iter->()) {
last if $i > 25;
print $i . "\n";
}

my $iter2 = create_iter(1, sub { $_[0] *= 2 });

while (my $i = $iter2->()) {
last if $i > 256;
print $i . "\n";
}
pq
 2007-04-27 13:56
#76292 #76292
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=GoodFella,26.04.2007, 23:56]Um den Sub-Namespace möglichst klein zu halten und logische Einheiten beeinander zu belassen?[/quote]
baeh, das macht man aber doch nicht mit einer verschachtelten subroutine.
eine anonyme sub reicht ja wohl voellig aus.
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 3 >| >> 21 Einträge, 3 Seiten



View all threads created 2007-04-26 20:29.