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


In reply to Should "use strict" complain if I use a variable that is not declared? by earthman

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.