in reply to Re^3: postfix syntax enlightenment
in thread postfix syntax enlightenment

Hi Ken,

Thank you for your answer and I have usually the highest regard for your posts (and I upvoted your answer even though I still disagree with it, because I think it is well explained). To set the record straight, I am not trying to invalidate Eily's example, far from that, I am just trying to understand what exactly is undefined behavior here. And I am still not convinced at all that:

my $var if $test;
and
my $var = 1 if $test;
are equivalent in terms of the behavior being defined or not. These are two quite different types of statements. Assuming just one second, only for the sake of argument, they had both a defined behavior, I would still consider the first one as almost entirely useless (and deserving to be undefined), and the second one as making some sense (although lacking clarity, to say the least). Therefore, if the author of the documentation meant to say that my $var = 1 if $test; also has undefined behavior, then I would submit that this should probably be added to the documentation, because having someone using this second type of construct is much more likely than than the first one.

Again, I am not saying that Eily is wrong, I just don't know and I truly would like to know. While I usually would probably not use something like:

my $var = 1 if $test;
I would really not swear that I have never used something like:
my $value = $1 if $foo =~ /^\w+(\d+)/; do_something($value) if defined $value;
And, as far as I can say, I would expect this to work fine.

Concerning the one-liners, I agree that they were very short examples I added at the last minute to my post, this is an improved version of them:

$ perl -Mstrict -Mwarnings -e ' my $c = 1 if 1; print $c;' 1 ~ $ perl -Mstrict -Mwarnings -e ' my $c if 1; print $c;' Use of uninitialized value $c in print at -e line 1.
I am not saying that observed behavior is describing the Perl standard, but since there is no real Perl 5 standard, in a certain way, only the compiler can tell us what to think when the documentation is ambiguous. And I think the documentation is definitely ambiguous in that specific case. Having said that, I perfectly understand the warning: "Future versions of perl might do something different..." Just not sure that it applies to something like:
my $var = 1 if $test;

Replies are listed 'Best First'.
Re^5: postfix syntax enlightenment
by kcott (Archbishop) on Mar 29, 2014 at 09:01 UTC

    It may be that you're reading more into the given example than is intended in the documentation. Examples tend to be short and to the point: complex examples can often obscure the main idea that the example is intending to convey. "my $x if ..." would be one of the shortest examples that showed a lexical declaration with a statement modifier.

    "... my, state, or our ..." are all keywords that introduce a lexical declaration. There's nothing in the documentation that says anything about how those keywords might be used: it mentions no restrictions or exemptions. Just because the example only shows "my $x", I see nothing that suggests more complex examples would behave any differently (with respect to producing in an undefined result which should not be relied upon). All of these would be equally valid examples but tend to (increasingly) hide the point being made (and might even suggest exclusion of simpler examples):

    my ($x) if ... my $x = 1 if ... my ($x, $y) = (1, 2) if ... my ($x, $y, $z) = (split /\s+/ => $spaced_tokens)[3 .. 5] if ...

    Similarly, "... modified with a statement modifier conditional or loop construct ..." mentions no restrictions or exemptions. The example uses "if"; however, there's nothing to suggest that any of the other modifiers (unless, while, until, for, foreach or when) would behave any differently (with respect to producing in an undefined result which should not be relied upon).

    For what it's worth, I played around with the OP code a bit when it was first posted. In one test, I added a check for whether $test1 was defined after "my $test1 = ... if ...;". In the first call to test(), $test1 was undefined; in the second call it was defined:

    $test1 is not defined. Use of uninitialized value $test1 in concatenation (.) or string at ./ +pm_example.pl line 13. test1 after hash assignment: '' i = 0 test1 after defaulting to i: '0' $test1 is defined. test1 after hash assignment: '0' i = 1 test1 after defaulting to i: '0'

    That looks like exactly the unpredictable results described in: "The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it."

    -- Ken

      Thank you very much, kcott, for your explanations, many thanks also to others who provided answers, especially Anonymous Monk for the very informative links provided and Eily for having initially pointed that undefined behavior in this thread. Since I certainly don't want to be bitten by unexpected undefined behavior, I will definitely make sure never to use such "conditional my" constructs in the future (and will remove them from existing code if I find any). Again, thanks to all monks who provided information on this subject.
Re^5: postfix syntax enlightenment ( y $x if 0; Trick my @array = () if 0; conditional declaration; state )
by Anonymous Monk on Mar 29, 2014 at 01:02 UTC
Re^5: postfix syntax enlightenment
by Anonymous Monk on Mar 29, 2014 at 02:40 UTC
    my with postfix if is the singular problem, regardless of any assignment, present or absent.