in reply to Why doesn't the flip-flop operator work in all scalar contexts?

You need to keep reading that page. Two more paragraphs down it says:
If either operand of scalar ".." is a constant expression, that operand is considered true if it is equal ("==") to the current input line number (the $. variable).
Your examples with filereading change $., but your other examples don't. That's the difference.

Replies are listed 'Best First'.
Re^2: When doesn't the flip-flop operator work in all scalar contexts?
by siracusa (Friar) on Oct 02, 2008 at 13:02 UTC

    Sigh. Thanks, apparently my RTFM skills are weak this morning.

    ...although, what do they mean by "constant expression?" Is $x ever a constant expression? What kind of expression doesn't "evaluate to a constant?"

    my $x = 1; for(1,2,3,4,5) { next if $x..$x; # never returns true! print "$_\n"; }

      You just demonstrated the difference between a 'constant value' and a 'constant expression'.

      UPDATE: Arrrgh, again I fell into the trap of not reading thoroughly. Please ignore.

      UPUPDATE: After testing more thoroughly, it seems that when something like $x is used instead of 1, something happens that is not consistent with the docs:

      for(1,2,3,4,5) { $.= $_; next if 1..1; print "$_\n"; } #### prints as expected 2 3 4 5 my $x=1; for(1,2,3,4,5) { $.= $_; next if $x..$x; # never returns true! print "$_\n"; } #### prints nothing. Why??? It doesn't test against $. and it doesn't +just test the value $x my $x = 1; my $y = 0; for(1,2,3,4,5) { $.= $_; next if $x..$y; # never returns true! print "$_ "; } #### prints nothing as well. If the flip and the flop happened at the +same round it would have printed something

      Tried to run it with -Dx but that showed too much information. Wasn't there a debugging flag that shows just the compiled byte code?

      UPUPUPDATE: corrected a copying mistake and explained the wrong output some more

        #### prints nothing. Why??? It doesn't test against $. and it doesn't just test the value $x

        $x is not a constant expression, so $. doesn't come into play. You're right about that bit.

        But you're wrong about it not just testing $x. The reason it never prints anything is that it flips again as soon as it flops since $x is always true.

        my $x=1; for(1,2,3,4,5) { next if (printf("flip at %s? %s\n",$_,$x?'yes':'no'),$x) .. (printf("flop at %s? %s\n",$_,$x?'yes':'no'),$x); print "$_\n"; }
        flip at 1? yes flop at 1? yes flip at 2? yes flop at 2? yes flip at 3? yes flop at 3? yes flip at 4? yes flop at 4? yes flip at 5? yes flop at 5? yes
      while (<$fh>) { next if 1 .. 1; print "$_\n"; }

      means

      while (<$fh>) { next if $.==1 .. $.==1; print "$_\n"; }

      so to do the same with a loop which counts over something other than $., you have specify it explicitly.

      for (1,2,3,4,5) { next if $_==1 .. $_==1; print "$_\n"; }

      what do they mean by "constant expression?"

      Short: Anything that Perl converts to a constant at compile-time.

      >perl -MO=Concise -e"print( 4 + 1 * 2 )" 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 5 <@> print vK ->6 3 <0> pushmark s ->4 4 <$> const[IV 6] s ->5 <--- 4+1*2 -e syntax OK >perl -MO=Concise -e"print( 4 + $x * 2 )" a <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v ->3 9 <@> print vK ->a 3 <0> pushmark s ->4 8 <2> add[t3] sK/2 ->9 \ 4 <$> const[IV 4] s ->5 | 7 <2> multiply[t2] sK/2 ->8 | <--- 4+$x*2 - <1> ex-rv2sv sK/1 ->6 | 5 <#> gvsv[*x] s ->6 | 6 <$> const[IV 2] s ->7 /

      Long: A constant expression is known to Perl to always return the same result. It includes constants (including those created by constant), most operators operating on constants, some builtin functions, and functions with the () prototype whose body consist entirely of a constant expression (as per Constant Functions in perlsub).

      Given

      sub PI() { 4 * atan2(1, 1) } use constant SOMENUM => rand(4);

      Example of constant expressions:

      4 5+6*7 4 * atan2(1, 1) PI SOMENUM
      ...although, what do they mean by "constant expression?"

      Yeah, good question. Constant expression means whatever perl constant-folds at compile time. Numeric and string literals are constant, most simple operators (arithmetic and logic and things like that, but not including x) are constant-folded iff all their arguments are constants, and so are a few named builtins like uc, most other expressions aren't. There are some corner cases (like the comma operator) and even some version differences, so if you want to know for sure what's constant-folded and what isn't, you may need to dump the code with use O "Deparse"; or even use O "Concise";. If in doubt, just compare to $. explicitly if you want that semantics.

      There are at least two other cases where an expression being constant matters in how your perl code is interpretted, though one of these might be a bug: Twin-lines japh and Re^3: A cleaner way of scoping variables.

Re^2: When doesn't the flip-flop operator work in all scalar contexts?
by wol (Hermit) on Oct 02, 2008 at 13:27 UTC
    So what happens if $. is incremented appropriately in the loop? Does it magically start working?

    Egads! It just worked!

    (Add you own caveats here)

    --
    .sig : File not found.