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

shifting trouble: shift's Rückgabewert ändert sich durch



<< |< 1 2 >| >> 11 Einträge, 2 Seiten
dukeofnukem
 2007-01-15 15:08
#73210 #73210
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
Alohá!

Sieht gut aus hier, grade registriert weil ich einfach keine Idee habe wie folgendes zu Stande kommt:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
# Get fh
sub get_fh {
print "\nARRAY IS: ", join (' ', @_);
my $class = shift;
print "\nARRAY IS: ", join (' ', @_);
my $file = shift or croak "specify file!\n";
print "\nARRAY IS: ", join (' ', @_);
my $option = shift or my $option = "dummy";
$file = abs_path($file) unless ( $file eq "tmpfile" );
print "\n FILE IS: ", $file;
print "\n OPTION IS: ", $option;


Wenn ich die Methode mit z.B. mit
Code: (dl )
$class->get_fh("/path/to/file", "write");

aufrufe, bleibt $option uninitialized!

Die Ausgabe gibt mir durchaus die korrekte Befüllung von @_ an, und die ersten beiden Parameter werden sauber runtergeshifted, doch wenn es an den letzten geht (bzw. die or-Bedingung evaluiert wird), klappts nicht.

Wenn ich die Überprüfung rausnehme und stumpf shifte ist alles wunderbar (bis auf die Tatsache daß ich keinen default-init auf $option machen kann).

Selbst wenn ich alternative checks auf Vorhandensein des dritten array-felds nutze wirft das alles über den Haufen:
Code: (dl )
   defined(\$_[0]) ? my $option = shift : my $option = "dummy";

sorgt für die gleiche Problematik: es wird weder mit "dummy" initialisiert noch der vorhandene Parameter geshifted und $option zugewiesen.

Bin auch mit perl -d durchgesteppt:
- das Übergabearray ist korrekt befüllt
- bei einfachem shift wird korrekt zugewiesen
- bei Überprüfung auf Existenz oder Rückgabwert von shift bleibt $option uninitialisiert

Das Problem muß tatsächlich mit der Überprüfung der Befüllung von $option zu tun zu haben; wenn ich folgendes mache
Code: (dl )
1
2
   my $option = shift;
my $option = "dummy" unless $option;

und mit perl -d durchsteppe, wird $option korrekt initialisiert doch durch die nächste Zeile wieder auf undef gesetzt.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
  DB<14> x $option
0 undef
DB<15> s
Fileclerk::get_fh(<laanger/path/to/File.pm>:65):
65: my $option = "dummy" unless ($option);
DB<15> x $option
0 'write'
DB<16> s
Fileclerk::get_fh(<laanger/path/to/File.pm>:66):
66: $file = abs_path($file) unless ( $file eq "tmpfile" );
DB<16> x $option
0 undef
DB<17>



Hab ich da was komplett falsch verstanden was die Überprüfung der initialisierung von Variablen angeht?

Wer kann das Rätsel lösen? :-)

TIA

DoN
drum&bass is a state of mind
renee
 2007-01-15 15:12
#73211 #73211
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Mach aus:
Code: (dl )
  my $option = shift or my $option = "dummy";


das hier:
Code: (dl )
  my $option = shift || "dummy";
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
dukeofnukem
 2007-01-15 15:21
#73212 #73212
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
das war ja mal schnell :-)

Vielen Dank!

(Hätte ich auch sehen müssen ~:-/ )

Dachte durch lazy evaluation hätte die erste Hälfte der or-Bedingung schon greifen müssen.

Noch eine Nachfrage: Was macht der compiler aus der doppelten 'my $option =' Deklaration? Ignoriert er die oder ist das generell ein syntaktischer Fehler?
drum&bass is a state of mind
dukeofnukem
 2007-01-15 15:23
#73213 #73213
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
...und warum setzt
Code: (dl )
my $option = "dummy" unless ($option);

auf undef statt zu prüfen?
drum&bass is a state of mind
renee
 2007-01-15 15:24
#73214 #73214
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn Du use warnings benutzt, bekommst Du eine Warnung!

Du solltest auch immer Wiki:[tt]use strict[/tt] benutzen...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
dukeofnukem
 2007-01-15 15:26
#73215 #73215
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
:blush: whooops - tatsächlich use strict vergessen :blush:
drum&bass is a state of mind
renee
 2007-01-15 15:27
#73216 #73216
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=dukeofnukem,15.01.2007, 14:23]...und warum setzt
Code: (dl )
my $option = "dummy" unless ($option);

auf undef statt zu prüfen?[/quote]
Es setzt die Variable auf "dummy":
Code: (dl )
1
2
/entwicklung 329> perl -e 'my $option = "dummy" unless $option; print $option'
dummy


Mit strict würdest Du bei dem Konstrukt einen Fehler bekommen (wenn Du nicht vorher schonmal die Variable deklariert hast - aber dann bekommst Du mit warnings eine Warnung)
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2007-01-15 15:28
#73217 #73217
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=dukeofnukem,15.01.2007, 14:08][...]
Selbst wenn ich alternative checks auf Vorhandensein des dritten array-felds nutze wirft das alles über den Haufen:
Code: (dl )
   defined(\$_[0]) ? my $option = shift : my $option = "dummy";

sorgt für die gleiche Problematik: es wird weder mit "dummy" initialisiert noch der vorhandene Parameter geshifted und $option zugewiesen.
[...][/quote]
So etwas würde man besser so schreiben:
Code: (dl )
my $option = defined $_[0] ? shift : "dummy"
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pq
 2007-01-15 15:32
#73218 #73218
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
my $x = "foo" if $cond;
my $y = "bar" or my $y = "baz";

sollte man nicht verwenden. my() ist eine deklaration, und die
mit einem modifier wie einem nachgestellen if zu
verknüpfen, ist nicht sauber. zudem ist nicht definiert,
was perl dann macht; es kann sich je nach version oder
plattform ändern.
besser:
my $x = $cond ? "foo" : "default";
my $y = "bar" || "baz";
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
dukeofnukem
 2007-01-15 15:32
#73219 #73219
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
komisch, jetzt klappts auch bei mir nicht mehr die obige debuggerausgabe zu reproduzieren ~:-/


Vielen Dank noch Mal!
drum&bass is a state of mind
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2007-01-15 15:08.