readey has asked for the wisdom of the Perl Monks concerning the following question:

Hoping this is the right place to post this, I would like to share a discovery which I have never heard of before. I have a directory containing a load of files which differ only in the number assigned to them e.g. file1.csv, file2.csv etc. etc.. There are usually more than 10 such files and I need them in numerical order not in the order; file1.csv, file10.csv, file11.csv etc. So I wrote a schwartztian transform to do the job and came up with this;
@sorted = map {$_->[0]} sort { $a->[1] <=> $b->[1] } map { [$_, /^file(\d+)\.csv$/]} @files;
What surprised me was that the regular expression actually returns $1, which is in this case an integer digit. So the RE is returning a scalar variable which is in fact what it matched and not the number of times it matched. Is this perl magic, does it happen because the RE is wrapped inside [] or have I missed a fundamental point somewhere? Or (at the risk of getting a big head) have I discovered something?

update (broquaint): title change (was Is this magic?)

Replies are listed 'Best First'.
Re: Is this magic?
by broquaint (Abbot) on Jan 07, 2003 at 16:27 UTC
    So the RE is returning a scalar variable which is in fact what it matched and not the number of times it matched.
    What you have seen here is a regex match in a list context. If there are capturing parens within the regex it will return what was captured in those parens, and if it lacks capturing parens it will return true or false (unless the /g modifier is in use then it will return what was matched). In a scalar context it merely returns whether the regex matched successfully e.g
    my $str = "foo bar baz"; print "[", $str =~ /\w+ /, "]", $/; # list no capture print "[", $str =~ /\w+ /g, "]", $/; # list no capture + /g print "[", $str =~ /(\w+) /, "]", $/; # list and capture print "[". $str =~ /\w+ /, "]", $/; # scalar __output__ [1] [foo bar ] [foo] [1]
    See man perlop for more info.
    HTH

    _________
    broquaint

(z) Re: Is this magic?
by zigdon (Deacon) on Jan 07, 2003 at 16:24 UTC

    I think the RE is returning the $1 because it's in list context, and not scalar context. The list operator ',' [] forces it into list context. So yes, it is magic, but it's white magic. :)

    Update: Corrected my (fairly terrible) mistake. Thanks for pointing this out bart.

    -- Dan

      The list operator ',' forces it into list context.
      That's nonsense. Haven't you ever heard of the scalar comma operator? Check out perlop, subsection "Comma operator":
      In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.

      It's the surrounding square brackets that provide the list context.

Re: Is this magic?
by readey (Sexton) on Jan 07, 2003 at 16:47 UTC
    Thanks peeps, you've cleared that up a treat.
Re: Is this magic?
by jdporter (Paladin) on Jan 07, 2003 at 17:51 UTC
    Ah, yes, another week on PerlMonks.

    Update: Please read this classic article by japhy on Lists, Arrays, and Context.
    (PodMaster++ for this excellent tip.)

    jdporter
    Porter's First Law of PerlMonks:
    Someone will ask this question at least once a week.