8 ms·
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 cre
by tocomment 15y ago
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/slurp_article.pod http://search.cpan.org/~drolsky/File-Slurp-9999.13/extras/sl...
- norkakn 15y agohttp://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 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.
- chromatic 15y agohttp://onyxneon.com/books/modern_perl/ http://onyxneon.com/books/modern_perl/ has PDFs in other page sizes and other electronic forms too.
- joslin01 15y agoYea, 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 this comment
- tocomment 15y agoI 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 ; <> } ;
- mdda 15y agoThe local $/ is the trick : It reset the line-end character to 'undef', which makes the <> line-slurp the whole file at once.
- abuzzooz 15y agoIf 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 <STDIN> 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.
- lawn 15y agomy $txt = do { local $/ = <$file>; }; or my $txt = do { local $/; <$file>; }; 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.
- sciurus 15y agoAgreed, 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, '<', $file ) or die "cannot open $file\n"; my $text = do { local( $/ ) ; <$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
- bgilroy26 15y agoCPAN'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"
- mst 15y agoRight. When looking at the core language, "There Is More Than One Way To Do It" becomes "More than one thing will compile to the same VM opcodes, so you can choose the one that best expresses your intent to the maintenance programmer." When looking at libraries, "There Is More Than One Way To Do It" becomes "More than one library will solve your problem and you're welcome to select the one that makes the speed/size/complexity/feature trade-offs that best fit the project at hand." This is, absolutely, initially more confusing than "there should be one obvious way to do it", but it has other advantages, especially in the long run.
- shanemhansen 15y agoThis is actually really simple in perl. The idiomatic way to do it would be: open(my $fh, "<", "file.txt") or die "wft?" my @lines = <$fh>; lines is now an array of lines, you can join them into a single string if you want.
- mapgrep 15y agoSlightly more idiomatic would be with a useful die (and a semicolon terminating the first line): open(my $fh, "<", "file.txt") or die "Error reading file: $!"; my @lines = <$fh>; To slurp into a string rather than an array of lines: open(my $fh, "<", "file.txt") or die "Error reading file: $!"; my $s = join('',<$fh>);
- ajross 15y agoOr just: my $data = `cat $file`; Some folks dislike the useful use of cat, but anyone who's ever read a shell script will recognize the idiom. And it's a trivial one-liner much simpler still than the python code .
- pdehaan 15y agoThis isn't exactly idiomatic Perl and fails completely in environments that don't have cat (Windows). For one-time uses there's not a problem. However, if you find yourself writing what amount to shell scripts in Perl, you might be better off just writing shell scripts.
- ajross 15y agoExcuse me? Who are you to determine what is and isn't "idiomatic"? And that you would try this kind of thing about perl of all languages is just shocking. What's saddest is that it's the lack of this kind of absurdist pursuit of robustness and purity is one of the things that has always best defined the perl community. Broadly, your argument seems to be that spawning processes in the external environment[1] (which, admittedly, is inherently nonportable) is a Bad Thing in perl, and that we shouldn't do it. When I rephrase it like that, does it sound as poo-flinging crazy to you as it does to me? [1] Let's be honest: a working "cat" is pretty much the single most portable thing you can put between the backticks. If you won't allow this, what will you permit?