Re: grep flip flop (range operator)
by frozenwithjoy (Priest) on Sep 13, 2012 at 06:40 UTC
|
My understanding is that with Range Operators, if you have 1 .. /Q/, the 1 is short for $. == 1, so it will flip on and start printing at the first line of input from a file. The last example you are using is the only one that is reading from a file and, therefore, is the only one that flips on and prints.
Edit: for those that are unfamiliar with $., is is a special variable that equals the "current line number for the last filehandle accessed" (see perlvar). | [reply] [d/l] [select] |
|
$ perl -le " print for grep { my $what = scalar($Q++==0 ..($_ eq q{Q}
+)); warn $what; $what } qw{ a b c Q r s }; "
1 at -e line 1.
2 at -e line 1.
3 at -e line 1.
4E0 at -e line 1.
Warning: something's wrong at -e line 1.
Warning: something's wrong at -e line 1.
a
b
c
Q
| [reply] [d/l] |
|
To make things a bit more readable, you could use the match-once operator like this:
perl -le " print for grep ?? .. /Q/, @ARGV " a b c Q r s
___
a
b
c
Q
| [reply] [d/l] |
|
|
|
|
BONUS STUMPER: For all of the ones that don't print, they do print if you replace 1 with 0; however, all elements are printed instead of stopping at Q (shown below). For the one that did print, the change to 0 causes it to not print. Anyone able to explain this?
a
b
c
Q
r
s
| [reply] [d/l] [select] |
|
perl -E 'say "Yes!" if $. == 0;'
$. uninitialized if there's no file open for reading (undef). undef is false. In a numeric comparison, undef is promoted to zero (or conceptually better, zero is demoted to false, and undef is promoted to false). Consequently, 0 .. is true, and the flip flop flips.
If warnings were enabled you'd get one. :)
| [reply] [d/l] [select] |
|
|
Whole list is printed, as after spotting 'Q' flip-flop goes to 'false' state and back to condition $. == 0 which is all the time true, so it sets flip-flop again to true.
| [reply] [d/l] |
Re: grep flip flop (range operator)
by Neighbour (Friar) on Sep 13, 2012 at 06:42 UTC
|
What are you expecting to get with 1 .. /Q/?
The following code prints nothing as well:
use Data::Dump;
Data::Dump::dd(1 .. /Q/);
If your match-list is empty, nothing matches, and nothing is printed.
However, this does not explain why the last command *does* print something :)
Edit: Upon further reading, it looks like the range operator isn't parsed in scalar context, as the following does print something:
perl -le " print for grep scalar 1 .. /Q/, @ARGV " a b c Q r s
Output:
a
b
c
Q
r
s
| [reply] [d/l] [select] |
|
Edit: Upon further reading, it looks like the range operator isn't parsed in scalar context, as the following does print something: perl -le " print for grep scalar 1 .. /Q/, @ARGV " a b c Q r s
I use perl -MO=Deparse,-p what you have is (scalar(1) .. /Q/)
you need scalar( 1 .. /Q/ ) to get nothing :)
| [reply] [d/l] [select] |
Re: grep flip flop (range operator)
by GrandFather (Saint) on Sep 14, 2012 at 01:07 UTC
|
| [reply] |