Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Re: Save all but line 32!

by cowens (Beadle)
on Sep 18, 2002 at 17:25 UTC ( [id://198923]=note: print w/replies, xml ) Need Help??


in reply to Re: Save all but line 32!
in thread Save all but line 32!

This confuses me. I don't see how this would work. It looks like it will print no lines since 32 .. 32 should return either 1 (the number of elements in the list) or 32 (the last element in the list) both of which are "true". I am betting the later, but I am not sure. Would you kindly point out where I am wrong?
perl -- executes perl
-i   -- in-place editing
-n   -- implict loop
-w   -- turn on warnings (why?)
-e   -- execute the following string as the program

print    -- print what is in $_ (only executed if the unless is  false)
unless   -- execute the previous command if the result of the following
            expression is 0, undef, or '' (or the equivalent)
32 .. 32 -- construct a list containing the numbers 32 through 32
filename -- the file to edit

Replies are listed 'Best First'.
Re: Save all but line 32!
by Abigail-II (Bishop) on Sep 18, 2002 at 17:33 UTC
    You don't understand context. An expression in scalar context doesn't mean it's evaluated in list context, and then the list is evaluated in scalar context.

    No, it means the expression is evaluated in scalar context. And .. doesn't act at all the same in scalar context as in list context. From the manual page:

    In scalar context, ".." returns a boolean value. The operator is bistable, like a flip-flop, and emulates the line-range (comma) operator of sed, awk, and various edi- tors. Each ".." operator maintains its own boolean state. It is false as long as its left operand is false. Once the left operand is true, the range operator stays true until the right operand is true, AFTER which the range operator becomes false again. It doesn't become false till the next time the range operator is evaluated. It can test the right operand and become false on the same evaluation it became true (as in awk), but it still returns true once. If you don't want it to test the right operand till the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does. The right operand is not evaluated while the operator is in the "false" state, and the left operand is not evalu- ated while the operator is in the "true" state. The precedence is a little lower than || and &&. The value returned is either the empty string for false, or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the end- point. You can exclude the beginning point by waiting for the sequence number to be greater than 1. If either operand of scalar ".." is a constant expression, that operand is implicitly compared to the $. variable, the current line number. Examples: As a scalar operator: if (101 .. 200) { print; } # print 2nd hundred lines next line if (1 .. /^$/); # skip header lines s/^/> / if (/^$/ .. eof()); # quote body
    Abigail

      I've read those paragraphs at least a dozen times since I first saw reference to the "flip-flop operator" in the spoiler for an obfu, one of erudil's or maybe on of yours, and I still have trouble applying it.

      If anyone has a less wordy, more .. um .. transparent description of the .. and ... in a scalar context, or even better a simple example of use that is self-contained and demonstrative, I for one would find that very useful.


      Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
        I managed to come up with the following code that is not quite groundbreaking, but which you may find useful. The '..' expression is false until first_condition is true (until $i == 3). It continues to be true until second_condition is true (the next number which is 3 mod 10). Playing around with the *_condition functions will help get the hang of things. It helped a bit for me -- I still am not entirely comfortable with the operator (at least in scalar context) myself, but I'm getting there.

        In Abigail-II's code, 32..32 is syntactic sugar for $.==32 .. $.==32. So when $. is equal to 32, the expression becomes true, and then becomes false for all subsequent evaluations. The unless reverses the logic so that each line of input is printed only if it's not #32. I like it!

        use strict; for my $i (0 .. 20) { if (first_condition($i) .. second_condition($i)) { print "true for $i\n"; } else { print "false for $i\n"; } } sub first_condition { return $_[0] == 5; } sub second_condition { return $_[0] % 10 == 3; } __END__ false for 0 false for 1 false for 2 false for 3 false for 4 true for 5 true for 6 true for 7 true for 8 true for 9 true for 10 true for 11 true for 12 true for 13 false for 14 false for 15 false for 16 false for 17 false for 18 false for 19 false for 20

        blokhead

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://198923]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-23 20:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found