Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this Perl one liner to check if a directory is empty work?

Tags:

glob

perl

I got this strange line of code today, it tells me 'empty' or 'not empty' depending on whether the CWD has any items (other than . and ..) in it.

I want to know how it works because it makes no sense to me.

perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'

The bit I am interested in is <.* *>. I don't understand how it gets the names of all the files in the directory.

like image 686
dsm Avatar asked Jul 14 '09 15:07

dsm


1 Answers

It's a golfed one-liner. The -e flag means to execute the rest of the command line as the program. The -l enables automatic line-end processing.

The <.* *> portion is a glob containing two patterns to expand: .* and *.

This portion

(q=not =)

is a list containing a single value -- the string "not". The q=...= is an alternate string delimiter, apparently used because the single-quote is being used to quote the one-liner.

The [...] portion is the subscript into that list. The value of the subscript will be either 0 (the value "not ") or 1 (nothing, which prints as the empty string) depending on the result of this comparison:

2 == (()=<.* *>)

There's a lot happening here. The comparison tests whether or not the glob returned a list of exactly two items (assumed to be . and ..) but how it does that is tricky. The inner parentheses denote an empty list. Assigning to this list puts the glob in list context so that it returns all the files in the directory. (In scalar context it would behave like an iterator and return only one at a time.) The assignment itself is evaluated in scalar context (being on the right hand side of the comparison) and therefore returns the number of elements assigned.

The leading + is to prevent Perl from parsing the list as arguments to print. The trailing .empty concatenates the string "empty" to whatever came out of the list (i.e. either "not " or the empty string).

like image 75
Michael Carman Avatar answered Oct 16 '22 22:10

Michael Carman