Kevin Walzer wrote:

I'm an experienced developer in several other languages (Python, Tcl,
AppleScript, JavaScript, C/Objective C), so I'm quite familiar with
structuring a program--but as I work on learning Perl, I find it
somewhat obscure, if not downright obfuscated. None of the other
languages I've worked with have the equivalent of the $_ implicit var,
for instance. Looking at some sample code online, I had to spend a
considerable amount of time looking up the various bits with sigils and
annotating them, cf:

open (INPUT, "< $_"); ##input from default $_ var

It is very bad to use a system function like open() without determining if it succeeded or failed. Also, most modern Perl programmers use the three argument version of open() and lexical filehandles.

open my $INPUT, '<', $_ or die "Cannot open '$_' because: $!";

Also, the File::Find::find() function callback function, which this code is part of, only allows you to access the current file name through the $_ variable, while in other contexts a lexical variable can be used instead of $_.


foreach (<INPUT>) {

A foreach loop operates on a list so perl has to read the entire file into a list in memory. This is usually written with a while loop which only reads one line at a time.

while (<INPUT>) {


    if(/$searchstring/i) { ##case-insenstive regex for $searchstring

Case-insenstive regex for the contents of $searchstring. A match operator does interpolation basically the same as a double quoted string. A better way would be to create $searchstring using the qr// operator with the /i option.


        $_ = substr($_, 0, 60); ##trim string to 60 chars

That is an inefficient way to truncate a string.  A better way would be:

substr( $_, 60 ) = ''; ##trim string to 60 chars

Or perhaps better:

substr( $_, 60, length(), '' ); ##trim string to 60 chars

As this modifies the string in-place.


        s/^\s*//; #trim leading space

That modifies every string, whether it contains leading whitespace or not. It should be written to only modify strings that actually contain whitespace:

        s/^\s+//; #trim leading space


        print "$File::Find::name\:$.\:\t$_\n"; #print filename followed by line
number followed by tab followed by matching line

The $. (current line number) variable only contains useful information from inside a while loop but does nothing useful from inside a foreach loop.


    }
}
close INPUT;

Perhaps this is idiomatic to you,

No, it is not. It looks like someone who doesn't understand Perl wrote this. You should be careful what you download off the internet. ;)


but it's very dense to me. And I have
a decade of development experience.



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.                   -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to