Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^3: Using grep and glob to find directories containing file

by LanX (Canon)
on Feb 03, 2013 at 23:45 UTC ( #1016877=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Using grep and glob to find directories containing file
in thread Using grep and glob to find directories containing file

> grep(@{[glob("$_/f*")]}

there are easier ways to count in list context,

grep { () = <$_/*> } <dir{1,2,3}>

(kind of a "half goatse" ;)

Cheers Rolf


Comment on Re^3: Using grep and glob to find directories containing file
Select or Download Code
Re^4: Using grep and glob to find directories containing file
by 7stud (Deacon) on Feb 04, 2013 at 00:35 UTC

    Despite the admonition not to use <> for globbing?

    So...list context on the left, which then creates an anonymous array, which array, when evaluated in boolean/scalar context, produces the length of the array?

      > So...list context on the left, which then creates an anonymous array, which array, when evaluated in boolean/scalar context, produces the length of the array?

      No arrays involved, not even anonymous!

      It's just a list-assignment in scalar context.

      I would say much more performant than the former solution.

      Cheers Rolf

      PS:

      > Despite the admonition not to use <> for globbing?

      Source?

      Then I don't understand. If there's no anonymous array somewhere, then there's no counting going:

      use 5.012; my $x = ('a', 'b', 'c'); say $x; --output:-- 'c'
      Lists don't return their length in scalar context--only arrays return their length in scalar context. Although, now I see it has the same effect in your example--because in list context glob() returns an empty list when there are no matches, and trying to retrieve the last element of an empty list is undef or some other false value.

        That's not a list, that's the comma operator in scalar context, which will disregard its left hand value and return its right hand value.

        So in my $x = ('a', 'b', 'c');, 'a' and 'b' get discarded, and 'c' gets assigned to $x, as your snippet proves. This behaviour is documented (see the link I gave) and also demonstrated by B::Deparse:

        $ perl -MO=Deparse -E '$x = ("a", "b", "c");' use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch' +, 'unicode_strings', 'unicode_eval'; $x = ('???', '???', 'c'); -e syntax OK

        However, =()= is an idiomatic way to enforce list context. The details are better explained in Perl Idioms Explained - my $count = () = /.../g than I could do it myself, but just to demonstrate that it works, consider the following.

        $ perl -MO=Deparse -E '$x =()= ("a", "b", "c"); print $x' use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch' +, 'unicode_strings', 'unicode_eval'; $x = () = ('a', 'b', 'c'); print $x; -e syntax OK $ perl -E '$x =()= ("a", "b", "c"); print $x' 3

        That's not a list

        Are you sure? "Learning Perl 6th ed", p. 46 says:

        A list literal (the way you represent a list value within your program) is a list of comma- separated values enclosed in parentheses. These values form the elements of the list. For example:
        
        (1, 2, 3) # list of three values 1, 2, and 3
        

        This behaviour is documented (see the link I gave)

        …which says:

        Binary "," is the comma operator…
        
        In list context, it's just the list argument separator, and inserts both its arguments into the list.

        > Lists don't return their length in scalar context

        Correct!

        With "goatse" it's a list _assignment_ = which in scalar context returns the number of list elements assigned.

        But this was a scalar assignment.

        >  my $x = ('a', 'b', 'c');

        The LHS of the assignment operator decides about the context.

        An example of scalar context of list context of assignment is

         while ( ($v,$k) = each %h )

        It will terminate as soon as each returns an empty list, not when the lists last element (here $k) is undef.

        Clearer now?

        Cheers Rolf

        PS: you replied to yourself twice.

        UPDATE

        I think analyzing the op-tree helps understanding the mechanism

        lanx@nc10-ubuntu:~/org$ perl -MO=Terse -e'$x= ()=qw(a,b)' LISTOP (0x9bd0fe0) leave [1] OP (0x9be01e8) enter COP (0x9bb8860) nextstate BINOP (0x9b3ca48) sassign BINOP (0x9b21a58) aassign [2] UNOP (0x9b218c0) null [142] OP (0x9be3e40) pushmark SVOP (0x9c14638) const [3] PV (0x9b1dee0) "a,b" UNOP (0x9c14598) null [142] OP (0x9b19820) pushmark OP (0x9b3c980) stub UNOP (0x9be8630) null [15] PADOP (0x9b21940) gvsv GV (0x9b1dec0) *x -e syntax OK

        (don't blame me for Larry's decision to call a list assignment aassign)

        You see assignment BINOP is like a function called with arguments (RHS,LHS) and RHS is evaluated according to LHS context and assigned to LHS. (thats decided a compile time)

        The RHS of the first BINOP is the second BINOP, not a list.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1016877]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2014-08-22 23:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (168 votes), past polls