Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Re^5: how to deal with incorrect command line argument

by muba (Priest)
on Oct 31, 2013 at 21:13 UTC ( #1060642=note: print w/replies, xml ) Need Help??

in reply to Re^4: how to deal with incorrect command line argument
in thread how to deal with incorrect command line argument

Then perhaps you'll find it helpful to see that line of code explained. It looks tougher than it is. Make yourself comfortable, because here we go!

The line of code as a whole, just for reference:

(-e) ? doTheWork($_) : warn qq{"$_" doesn't exist!} for @ARGV;

So let's look at it one chunk at a time. First chucnk: (-e).

In Perl, many operators and functions use the default variable $_ if no other variable was specified. -e is no different, so you can think of this chunk as if it were (-e $_). The question here is, where does $_ get its value from? We'll get there in a minute.

One thing to remember for now, though, is that I have a pet name for $_ I don't call it "dollar-sign underscore", I don't call it "default variable", I call it "it." When my eyes read $_, my mind sees "it". When I see -e $filename, I read "does filename exist?", when I see -e $_ I read "does it exist?", and when I see an implied $_ as is the case in our code fragmet (-e), I read that as "does (it) exist?."

Let's move on.

The next chunk is the ? thingy, which is part of the ternary operator ?:. A ternary operator, as the name might give away, takes three operands (as opposed to a binary operator which takes two operands and a unary operator which takes only one).

You can think of ?: as an if-then-else shorthand, primarily used in constructions such as these:

@ages = (15, 18, 24); foreach $age (@ages) { print "At age $age you ", ($age >= 21 ? "can" : "can't"), " buy a +beer.\n"; }
At age 15 you can't buy a beer. At age 18 you can't buy a beer. At age 24 you can buy a beer.

So basically the syntax for the ?: operator could be summarised as If-Expression ? Then-Expression : Else-Expression

In our particular case, the If-Expression, or the condition, is (-e), or (-e $_), in other words, "if this file exists". The Then-Expression, the thing to evaluate and return when the condition is true, is doTheWork($_). So if the file exists, we call a subroutine named doTheWork, passing it the file name as an argument. The Else-Expression, which is only evaluated and returned when the condition isn't true, is the warn part, which I think is self-explanatory.

(-e) ? doTheWork($_) : warn qq{"$_" doesn't exist!}

Long story short, the above code simply reads as:

Perl English -------------------------------------------- (-e) does (it) exist? ? then doTheWork($_) do the work with it : else warn qq{...} warn that it doesn't exist.

Then there's just one more part of the code that we haven't had, and that's the final for @ARGV. In Perl, for and foreach are synonyms, and you use them to loop over the elements of a list. (In many cases, this list will simply be an array, but let's not dive into the subtle differences between lists and arrays now.) Traditionally, you would see them in fragmens of code such as these:

foreach $name (@all_names) { print "The next name is $name\n."; }

Which, using the default variable, can be shortened to

foreach (@all_names) { print "The next name is $_\n."; }

In simple cases such as these, where there's only one statement inside the body of the loop, Perl allows you to tack a statement modifier to the end of the statement, allowing you to shorten above fragment even further:

print "The next name is $_\n" for @all_names;

One thing to note is that the parens around @all_names, which are mandatory in the traditional notation, aren't necessary in statement modifiers.

for and foreach aren't the only statement modifiers: if, while, and until can also be used in the same way:

@names = qw(Alice Bob Charlie); print "$_ is a person.\n" for @names; # Prints: # Alice is a person. # Bob is a person. # Charlie is a person. @fruits = qw(Apple Banana Cherry); print shift(@fruits), " is a fruit.\n" while @fruits; # Prints: # Apple is a fruit. # Banana is a fruit. # Cherry is a fruit. $age = 18; print "You can't buy a beer at age $age\n." until ++$age >= 21; print "Congratulations! You can buy beer now, you're twenty-one!\n" if + $age == 21; # Prints: # You can't buy a beer at age 19 # You can't buy a beer at age 20 # Congratulations! You can buy beer now, you're twenty-one!

So that answers that question: where does the implied $_ in (-e) get its values from? It gets it from iterating over the contents of @ARGV.

Perl English -------------------------------------------- (-e) does (it) exist? ? then doTheWork($_) do the work with it : else warn qq{...} warn that it doesn't exist for @ARGV for every single command line argument

Replies are listed 'Best First'.
Re^6: how to deal with incorrect command line argument
by marinersk (Priest) on Oct 31, 2013 at 21:28 UTC
    So very well done.

    Does this qualify for a FAQ or something?

      Nah, barely. The line of code just shows what Perl is good at: using minimalist building blocks, combining into something actually meaningful.

      In itself, the ternary operator ?: is not so surprising. It makes its appearance in many languages, such as C, C++, C# (I believe), Obj-C (I believe), Java (I believe), JavaScript, and likely many more.

      Statement modifiers also aren't very mention-worthy, in that many languages in the C-family allow you to

      if (THIS) THAT;

      Whereas Perl requires the curly braces around it:

      if (THIS) { THAT; }

      But not if you write it as

      THAT if THIS;

      So statement modifiers are just one of those things in Perl's syntax that make Perl Perl, however it's not something we don't know in one form or another from other languages.

        Yeah, I remember the ternary iffrom C; didn't use it very much. I'd rather write code that a new developer can read slightly more englishly, and the braces, newlines, and indentation give a fair bit of intuition to where the code is going.

        I know I carry a lot of that prejudice into my Perl, but I rarely get complaints about my Perl being unreadable (only my variable names, which I staunchly continue to lay out in my peculiar 3x2 format -- but the code itself almost never gets complaints).

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2021-03-02 05:34 GMT
Find Nodes?
    Voting Booth?
    My favorite kind of desktop background is:

    Results (38 votes). Check out past polls.