Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size of array generated by <>?

If I want to find the size of an array generated by <>, why doesn't the following work?

print "Number of .DOC and .PDF files is: " scalar(<*.PDF *.DOC>);

It gives the name of the first matching file instead.

like image 737
CJ7 Avatar asked Dec 03 '25 21:12

CJ7


1 Answers

Let's start by clearing up some of your misconceptions.

  • glob[1] never returns an array. Operators don't return arrays[2]; they return scalars. Sometimes none, sometimes one, sometimes many.

  • scalar affects operators, not the values they return. Specifically, scalar causes the operator within to be evaluated in scalar context.

  • How an operator is affected by context is up to each individual operator. The only constant is that they must return exactly one scalar in scalar context. There is a lot of variety in what they choose to return in scalar context.

In scalar context, glob acts an iterator, returning the next item it would have returned in list context, or undef to signal there are no further values to return.


Solutions:

  • A memory-efficient solution:

    my $num_files = 0;
    ++$num_files while <*.PDF *.DOC>; 
    print "Number of .DOC and .PDF files is: $num_files\n";
    
  • A faster solution:

    my @qfns = <*.PDF *.DOC>; 
    print "Number of .DOC and .PDF files is: " . @qfns . "\n";
    
  • An inlined version of the above:

    print "Number of .DOC and .PDF files is: " . @{[ <*.PDF *.DOC> ]} . "\n";
    
  • An even faster, less wasteful, but more advanced solution:

    print "Number of .DOC and .PDF files is: " . ( () = <*.PDF *.DOC> ) . "\n";
    

    The list assignment operator in scalar context returns the number of scalars returned by its RHS.

  • Cleaner/clearer?

    my $num_files = () = <*.PDF *.DOC>;
    print "Number of .DOC and .PDF files is: $num_files\n";
    

  1. <*.PDF *.DOC> is a shortcut for glob(qq<*.PDF *.DOC>)

  2. Except for @a in certain situations (including \@a, @a = LIST, and array manipulators like push @a, LIST).

like image 190
ikegami Avatar answered Dec 06 '25 13:12

ikegami