Live data from Hacker News

Python for Perl programmers

everythingsysadmin.com

11–20 of 40 posts

Re: Python for Perl programmers

#11

Can someone please make a Perl for Python programmers? It actually took me 30 minutes today to figure out how to do: text=open('file.txt').read() without creating 3-5 lines of code which seems excessive for a simple operation. There are apparently 20 ways to do it in Perl and they need their own CPAN library for it :-( [1] [1] http://search.cpan.org/~drolsky/File-Slurp-9999.13/extras/sl...

CPAN's ecosystem of packages are not really like Python's Libraries. There are packages for very small jobs such as doing IO or processing command line options (getopts) as well as packages that serve as whole ORMs or web frameworks, so it's considered easy to import File::Slurp even if you've never used it before, whereas it seems like the idea of using a library on the scale of Scipy for something like that would be silly.

My understanding is that Python usually has one established way of doing something, and what you find when you search "Python foo", what you find is usually what you want. Perl has more of a market based approach. I don't think "There Is More Than One Way To Do It" is intended to encourage the reinvention of wheels, that isn't really the Perl way. There often is an established way to do it in Perl and that way is File::Slurp or Template::Toolkit or Moose or DBI::DBD. The packages are great, they have maintainers so they can be updated, and as long as you know to use CPAN, they are easy to find.

On the other hand, that means the difference between a beginner who has problem X and says "Oh I'll look on CPAN for the source of the most popular package for X and see the examples the author put in" and a beginner who says "I don't know how to do that in Perl, where's a tutorial online?" is huge.

A couple of weeks ago there was a big to do in the Perl community that there needed to be more well-written up-to-date results for "how-to" searches. I think the reason that the community got into that situation is that for people who know to use CPAN, the quality curation is taken care of. It is always clear what the top 1 or top 3 packages are for a given use and the place to start is looking at the examples in that package's documentation.

TL;DR : For Perl, CPAN's packages serve as 'reuseable code' as well as ORMs, and web frameworks etc, whereas it seems to me that Python will port most pieces of reusable code into the main language itself.

Edited: Replaced "I don't need to do that in Perl" with "I don't know how to do that in Perl"

Re: Python for Perl programmers

#12
Python people tend to always compile their regular expressions; I guess they aren't used to writing throw-away scripts like in Perl

This is so that the RE isn't compiled each time it's used. These days the RE module maintains an internal cache for compiled RE's, but that wasn't always the case.

The 1.5.2 docs for compile() say "using compile() is more efficient when the expression will be used several times in a single program" while the 2.7.2 docs add the note that "the compiled versions of the most recent patterns passed to re.match(), re.search() or re.compile() are cached, so programs that use only a few regular expressions at a time needn’t worry about compiling regular expressions."

Edit: apparently the cache was present in 1.5.2; it just wasn't documented. In 1.5.2 the cache size was 20. In 2.0 it was increased to 100.

Still: explicit is better than implicit.

As well, I find assigning the RE to a well-named variable tends to make for more readable code. RE patterns can be horribly ugly and I like to get their definitions out of the way of the logic using them.

Re: Python for Perl programmers

#13
post #8

Earlier quoted context omitted.

Yea, my $file_handle = open(file.txt) my $text; while (read $file_handle, $buff, 1024) { $text = $buff } read returns the number of characters read (0 when it's finished which will end the loop). I don't know of any generic "read" function, so it's up to you to define how many characters at a time and give the $buffer scalar to read into. it's just a different way of doing things norkakn is a better resource than thi…

I ended up going with this one for better or worse. I'm afraid I still don't quite understand it: my $text = do { local( @ARGV, $/ ) = $file ; } ;

The local $/ is the trick : It reset the line-end character to 'undef', which makes the line-slurp the whole file at once.

Re: Python for Perl programmers

#14
post #8

Earlier quoted context omitted.

Yea, my $file_handle = open(file.txt) my $text; while (read $file_handle, $buff, 1024) { $text = $buff } read returns the number of characters read (0 when it's finished which will end the loop). I don't know of any generic "read" function, so it's up to you to define how many characters at a time and give the $buffer scalar to read into. it's just a different way of doing things norkakn is a better resource than thi…

I ended up going with this one for better or worse. I'm afraid I still don't quite understand it: my $text = do { local( @ARGV, $/ ) = $file ; } ;

If you don't understand it, why use it? Is it that important for you to do this in one line of (relatively obscured) code, than in 2-3 lines of readable code?

For the record, the do() block defines @ARGV (which normally holds the command-line arguments) to contain the value of the $file (presumably a file name), and sets $/ (which is the input record separator) to an undefined value. In Perl, is synonymous to which makes it read from stdin. Since @ARGV now contains a file name, Perl will open this file for reading. Since $/ is undefined, Perl will enter in "slurp" mode, and will gobble up the whole file in one shot. Since this is the last statement in the do() block, it will be returned as its value, and stored in $text.

Lots of Perl magic happening here. I advise you against using such shortcuts.

Re: Python for Perl programmers

#16
post #7

Can someone please make a Perl for Python programmers? It actually took me 30 minutes today to figure out how to do: text=open('file.txt').read() without creating 3-5 lines of code which seems excessive for a simple operation. There are apparently 20 ways to do it in Perl and they need their own CPAN library for it :-( [1] [1] http://search.cpan.org/~drolsky/File-Slurp-9999.13/extras/sl...

http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf Perl isn't batteries included, but its packages are usually actually tested on multiple versions. This allows for the community to move on its own. There is no dictator, by design. Try #perl for help as well, or the package channel if there is one.

http://onyxneon.com/books/modern_perl/ has PDFs in other page sizes and other electronic forms too.

Re: Python for Perl programmers

#17
post #2

Anyone have the opposite? I've been working in Python for a few years but now I'm taking a Perl class.

I've not used Perl in any real way for years but I am now brushing up on it again.

You can do neat one-liners in Python or Ruby but I've always liked Perl for this kind of thing.

I also have a weird penchant for using BASH scripting to do quite complicated things. Just because it can.

Re: Python for Perl programmers

#18
post #8

Earlier quoted context omitted.

Yea, my $file_handle = open(file.txt) my $text; while (read $file_handle, $buff, 1024) { $text = $buff } read returns the number of characters read (0 when it's finished which will end the loop). I don't know of any generic "read" function, so it's up to you to define how many characters at a time and give the $buffer scalar to read into. it's just a different way of doing things norkakn is a better resource than thi…

I ended up going with this one for better or worse. I'm afraid I still don't quite understand it: my $text = do { local( @ARGV, $/ ) = $file ; } ;

my $txt = do { local $/ = ; };

or

my $txt = do { local $/; ; };

are as I know the preferred ways to do it. As a previous comment explained, $/ is the record separator and when you localize it it's value is set to undef. Which means we read the whole filehandle (the second part). As a do block evaluates to the value of the last expression, the contents of the file is the result of the whole expression.

If you're serious about Perl I recommend Modern Perl which is a 250 page really good introduction for the language, intended for programmers.

Re: Python for Perl programmers

#19
post #8

Earlier quoted context omitted.

Yea, my $file_handle = open(file.txt) my $text; while (read $file_handle, $buff, 1024) { $text = $buff } read returns the number of characters read (0 when it's finished which will end the loop). I don't know of any generic "read" function, so it's up to you to define how many characters at a time and give the $buffer scalar to read into. it's just a different way of doing things norkakn is a better resource than thi…

I ended up going with this one for better or worse. I'm afraid I still don't quite understand it: my $text = do { local( @ARGV, $/ ) = $file ; } ;

Agreed, the trick with a local ARGV and the null filehandle is too clever. Don't copy code you don't understand! I think opening the file is much clearer.

    open( my $fh, ' } ;

  http://perldoc.perl.org/perlopentut.html
  http://perldoc.perl.org/functions/do.html
  http://perldoc.perl.org/functions/local.html
  http://perldoc.perl.org/perlop.html#I%2fO-Operators

Re: Python for Perl programmers

#20
post #6
post #3

Not mentioned is the common idiom of assigning regexp matches. In perl, > my ($a, $b) = '12' =~ /(\d)(\d)/; In python, > (a, b) = re.match('(\d)(\d)', '12').groups() Note the python code here will throw an AttributeError if the match fails, whereas the perl will just assign undef to the variables.

Alternatively, use named captures: > obj = re.match('(?P \d\d)(?P \w+)') > id = obj.group('id') > name = obj.group('name')

Nice!
Post reply on HN