in reply to Pulling out pairs

while (<>) { chomp; (my ($key, $val) = split /:/) == 2 or next; }

    -- Chip Salzenberg, Free-Floating Agent of Chaos

Replies are listed 'Best First'.
Re: Re: Pulling out pairs
by blakem (Monsignor) on Dec 13, 2001 at 07:44 UTC
    Thats rather clever.... There is a subtle issue with extrapolating that particular idiom though. Suppose we wanted to match lines of exactly four fields, but were only interested in the first two fields of such lines:
    dog:cat:pig <== skip, only has three fields Amy:Ann <== skip, only has two fields ape:ant:bug:car <== match this line (it has four fields) but we only need to keep 'ape' and 'ant'

    Tweaking the code above, we might think that this will do the trick for us:

    while (<DATA>) { chomp; (my ($first, $second) = split /:/) == 4 or next; print "$first $second\n"; } __DATA__ dog:cat:pig Amy:Ann ape:ant:bug:car
    However, that doesn't seem to work for us, nothing gets printed. In fact, try as we might, we can't construct any line at all that passes the IDIOM==4 test.

    So, does anyone want to guess why IDIOM==4 is so different from IDIOM==2?

    Update: As an added hint, testing for IDIOM==3 will match the 'dog:cat:pig' line....

    -Blake

      The problem is that the optimiser will see:
      ($a, $b) = split /:/
      And know that things can go faster by turning that into:
      ($a, $b) = split /:/, $_, 3
      thus you actually should write:
      (my ($a, $b) = split /:/, $_, 5) == 4 or next;
        Well done. That's exactly what I was getting at.

        (I would have just /msged this response, except you cant /msg anonymonk....)

        -Blake