Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: putting text into array word by word

by tobyink (Canon)
on Jan 09, 2012 at 21:23 UTC ( [id://947072]=note: print w/replies, xml ) Need Help??


in reply to putting text into array word by word

Easy...

use strict; use autodie; open my $infile, '<', '/home/tai/tmp/sm-error-report.txt'; my @words = split /\W+/, do { local $/ = <$infile> }; print "$_\n" foreach @words;

Replies are listed 'Best First'.
Re^2: putting text into array word by word
by jms53 (Monk) on Jan 09, 2012 at 23:26 UTC
    Thanks for reminding me on the importance of commenting code.

    (I totally had no difficulty with your regexp)

    But I agree that not only are there more than one ways to do it, there are also some which require more experience ;)

      The only thing I used that could be accused of being slightly obscure is:

      do { local $/ = <$infile> }

      This is a fairly commonly used idiom for reading an entire file into a single string, but exactly how it works is somewhat obscure.

      Firstly, when you call <$filehandle>, Perl reads a single line from the file $filehandle. See perldoc -f readline

      Secondly, the variable $/ is used by Perl's file reading function to indicate what character to use as a line terminator (technically it's called the record separator). So normally, $/ is set to "\n". If you set $/ to undef, then Perl won't treat any characters as line terminators, so the readline function will simply read the entire remainder of the file. See perldoc -f readline and perldoc perlvar

      So, just based on the above knowledge, we can slurp the entire contents of a filehandle into a string like this:

      $/ = undef; my $string = <$filehandle>;

      But actually, what if other parts of our code rely on $/ being set to "\n"? We don't want to permanently undefine it.

      my $old_terminator = $/; $/ = undef; my $string = <$filehandle>; $/ = $old_terminator;

      Because temporarily changing the value of a variable is such a common need, Perl provides a shortcut. The local keyword allows you to set a new temporary value for a variable for a particular code block, such that the variable's old value will be automatically restored at the end of the block. See perldoc -f local. So our code becomes:

      my $string; { local $/ = undef; $string = <$filehandle>; }

      But = undef is redundant because all newly declared scalar variables (including local ones) are undefined. So now we have:

      my $string; { local $/; $string = <$filehandle>; }

      Now, the do block allows Perl to run a block of code and return the result of the last statement. See perlsyn. So our code can become:

      my $string = do { local $/; <$filehandle>; }

      The last simplification relies on the fact that in the following statement:

      local $/ = <$filehandle>

      Perl does things in this order:

      1. Localizes $/, setting it to undef.
      2. Reads the file - the entire file because $/ is undef.
      3. Performs the assignment.

      Thus we end up with the situation where you can read the entire contents of an open file handle into a string using:

      my $string = do { local $/ = <$infile> };

      Now, of course I could have included the entire explanation above as a comment, but I try to stick to a policy of never writing comments which are longer than the code itself.

        Far from me to accuse your code, rather I'm thankful for showing it to me, it's just that while Perl is a great language for coding (and damn logical on its syntax), there are far too many elements that still appear extremely obscure to me. My main issue was that you didn't seem to have a handle <FILE> which I assumed to be a requirement for reading files, and then this line:

         my @words = split /\W+/, do { local $/ = <$infile> };

        thank you very much however for explaining the local scope of $/. that will most certainly come in handy in the upcoming term.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2024-04-25 15:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found