Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Range operator; flip but prevent flop, and make immediate flip

Tags:

perl

perl -wle 'print join " ", grep /3/ .. undef(), 1..10'

outputs 3 4 5 6 7 8 9 10

Q1: Is there better way than undef to prevent flop?

Q2: How to force left part of range operator to unconditional true (ie. true .. /7/)?

UPDATE:

perl -wE 'say join " ", grep { ((/7/ .. undef)||1) ==1 } 1..10'

could be used as true .. /7/ replacement.

like image 934
mpapec Avatar asked Jun 04 '14 14:06

mpapec


2 Answers

  1. Any false expression that isn't constant-folded to a number will do.

    perl -wE'say join " ", grep $_==3 .. undef, 1..10'
    
    perl -wE'say join " ", grep $_==3 .. do{0}, 1..10'
    
    perl -wE'say our $FALSE; say join " ", grep $_==3 .. $FALSE, 1..10'
    

    Without a flip-flop.

    perl -wE'my $ok; say join " ", grep $ok ||= $_==3, 1..10'
    
  2. If you want the boolean opposite of something, use negation!

    perl -wE'say join " ", grep !($_==8 .. undef), 1..10'
    

    Without a flip-flop.

    perl -wE'my $done; say join " ", grep !($done ||= $_==8), 1..10'
    

    Ok, so I changed 7 to 8. To actually match on 7,

    perl -wE'my $last; say join " ", grep { my $x = ($_==7 .. undef); !$x || $x == 1 } 1..10'
    

    Without a flip-flop.

    perl -wE'my $done; say join " ", grep { my $rv = $done; $done ||= $_==7; !$rv } 1..10'
    
like image 173
ikegami Avatar answered Oct 17 '22 09:10

ikegami


Q1

Use the *FAIL verb:

print join " ", grep /3/ .. /(*FAIL)/, 1 .. 10;

Which can be abbreviated to just *F:

print join " ", grep /3/ .. /(*F)/, 1 .. 10;

And for the TIMTOWTDI:

print join " ", grep /3/ .. /(?!)/, 1 .. 10;
like image 27
Zaid Avatar answered Oct 17 '22 11:10

Zaid