http://www.perlmonks.org?node_id=1007352

jaffinito34 has asked for the wisdom of the Perl Monks concerning the following question:

I just started a script where I take in a text file (words.txt) where there is a new word each line. I used a while loop to read each line and a split to assign the words to a variable. My problem is that the output is not the word, it is the number of characters plus one. For example, the first word is 'tutor' and the print statements prints '6'. I'm thinking its because of the newline that it is adding one but even so, I don't know why its not printing the string. Ive used this type of statement before and never had issues.

#! /usr/bin/perl open (WORD, '<', 'words.txt'); while ($lines = <WORD>){ @word = split "", $lines; print @word."\n"; } print "\n\n";

Replies are listed 'Best First'.
Re: while loop returning numbers not strings
by blue_cowdawg (Monsignor) on Dec 05, 2012 at 18:19 UTC

    OK took your code at face value and made some fundamental changes:

    #!/usr/bin/perl use strict; while ($lines = <DATA>){ $word = split "", $lines; print $word."\n"; } print "\n\n"; exit 0; __END__ tutor teacher tinker sailor
    and when I ran it got:
    $ ./fix.pl Global symbol "$lines" requires explicit package name at ./fix.pl line + 5. Global symbol "$word" requires explicit package name at ./fix.pl line +6. Global symbol "$lines" requires explicit package name at ./fix.pl line + 6. Global symbol "$word" requires explicit package name at ./fix.pl line +8. Execution of ./fix.pl aborted due to compilation errors.
    which is not too surprising. So the next set of changes:
    #!/usr/bin/perl use strict; while (my $lines = <DATA>){ my $word = split "", $lines; print $word."\n"; } print "\n\n"; exit 0; __END__ tutor teacher tinker sailor
    and now when we run it we get:
    $ ./fix.pl 6 8 7 8
    pretty much as you describe. So let's make another change:
    #!/usr/bin/perl use strict; while (my $lines = <DATA>){ my ($word) = split "", $lines; print $word."\n"; } print "\n\n"; exit 0; __END__ tutor teacher tinker sailor
    which gives us:
    $ ./fix.pl t t t s
    At this point I have a couple of comments to make:
    1. Remember: the function split() returns an array based on the regex designating where to split the string. In this case you pass in an empty string which causes your $lines variable to be split on every character. (was that your intention?)
    2. Without the enclosing parenthesis around $word you are using an array in a scalar context which means you are going to get the length of that array as a scalar not the value of the array itself.

    Hope this helps you on your way....


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: while loop returning numbers not strings
by ww (Archbishop) on Dec 05, 2012 at 18:21 UTC
    See split.

    from perldoc -f split:

    split /PATTERN/,EXPR,LIMIT split /PATTERN/,EXPR split /PATTERN/ split Splits the string EXPR into a list of strings and returns +that list. By default, empty leading fields are preserved, and +empty trailing ones are deleted. (If all fields are empty, they +are considered to be trailing.) In scalar context, returns the number of fields found. ....

    Try splitting to an array, @words and printing them....

    #!/usr/bin/perl use 5.014; # 1007352 # error here: $word = split "", $lines; my $lines = "foo bar baz bat read the docs; they're often helpful."; my @word = split "", $lines; # $word replaced with @word say @word;

    OR (perhaps preferably)

    #!/usr/bin/perl use 5.014; # 1007352 # error here: $word = split "", $lines; my $lines = "foo bar baz bat read the docs; they're often helpful."; my @word = split " ", $lines; # $word replaced with @word; "" replace +d with " " my $word; for $word( @word) { say $word; }
Re: while loop returning numbers not strings
by SuicideJunkie (Vicar) on Dec 05, 2012 at 18:11 UTC

    What do you think split is doing, and why are you using a scalar to store the result?

    Try changing $word to @words

      Even using @words the code in the OP will print the length of each array since the print statement is using the . operator to concatenate.

      my @words = qw( this is the end ); print "words array is this long ".@words."\n"; print @words , "\n"; __END__ words array is this long 4 thisistheend

      I'm trying to split the file.. each line is a new word

        ...I take in a text file (words.txt) where there is a new word each line.

        If each line is one word, splitting isn't necessary. Adapting your script, you can do the following:

        #!/usr/bin/env perl use strict; use warnings; open my $words, '<', 'words.txt' or die $!; while ( my $word = <$words> ) { print $word; } print "\n\n"; close $words;

        You may have noticed from the excellent responses that lexical variables (my) are used. It's best to follow this practice--even with file handles. Also, always use strict; and use warnings;. It's also best to handle open errors, in case there was a problem opening a file.

        Hope this helps!

Re: while loop returning numbers not strings
by Rudolf (Pilgrim) on Dec 05, 2012 at 18:27 UTC

    Evaluating @word like so will return a number; you can put your array into double quotes:

    print "@word\n";

    However, I think since your already going through the lines your better off just doing this:

    while( my $line = <WORD> ){ print $_; }

    Update: I see now that split is the problem, and putting it into scalar context