When designing a class, I have developed the habit of allowing the constructor to take, in the arguments passed to the new() method, extra properties with which to prepopulate the object . This looks something like:
sub new { ... my %self = %{$_[0]} if ref $_[0]; ... }
Recently, I discovered that there is a major problem with the preceding method. The problem is that the condition prevents the "my" if the condition is false and, furthermore, strict does not complain that the "my" failed (or may fail) to occur. If the conditional prevents %self from being declared, using %self results in unexpected behavior that I depended upon "use strict" to prevent.
The following small code example illustrates the problem:
use strict; use warnings; my $a = testref1(); my $b = testref1(); $b->{test}=""; $a->{test}="hello world"; print $b->{test} . "\n\n"; my $c = testref2(); my $d = testref2(); $d->{test}=""; $c->{test}="hello world"; print $d->{test} . "\n\n"; sub testref1{ my %x = %{$_[0]} if ref $_[0]; print "testref1:" . \%x . "\n"; return(\%x); } sub testref2{ my %x; %x = %{$_[0]} if ref $_[0]; print "testref2:" . \%x . "\n"; return(\%x); }
The output on my machine looks like:
testref1:HASH(0x9f952c4) testref1:HASH(0x9f952c4) hello world testref2:HASH(0x9f95864) testref2:HASH(0x9f7b7a4)
What is notable about the output is that the addresses of the hash references returned from testref1 refer to the same hash, while testref2 returns references to two different hashes. This can be further seen by assigning data to the $a hashref and printing this data using the $b hashref. The result, in my production code, is that the new() method of my classes returns the same object over and over, when I would have preferred to have gotten a new() one.
I have no problem separating the variable declarations from any conditions wherever it occurs in my code, but I expected strict to warn me about a failure to declare a variable. When I got no messages from strict, I assumed (incorrectly) that the declaration was exempt from the condition. Should strict complain about a conditional declaration?
Thanks!
Michael Krebs
SpeakBlast.com
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |