Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Re: map split vs array split

by FunkyMonk (Chancellor)
on Jul 30, 2007 at 23:03 UTC ( #629687=note: print w/replies, xml ) Need Help??

in reply to map split vs array split

I don't understand any of your questions, but I'll try and answer what it is I think you're asking. I beg your forgiveness if I'm wrong.

my @words = map { split } <FH>;

Four things are happening here...

  • <FH> is being evaluated in list context because of map. So it will return a list of lines from FH.
  • split will take each of those lines in turn, and split them by it's default, which is whitespace (it's more complicated than that, see split for the details). split returns a list of the words in a line
  • map takes each list returned by split and adds them to @words
  • @words ends up as an array of words, taken from each line in your file.

Why is this evaluating split of array to scalar?

Because it's within a string. Perl evaluates print "\@lines1 is @lines1" as print '@lines1 is ' . @lines1. Concatenation forces scalar context on its operands. scalar @lines1 returns the number of element in the array.

See my reply below for the real answer to this.

print "@lines1" is treated magically: each element of @lines1 is printed, separated by a space.

update: ysth pointed out that what I'd written was wrong. Sorry about that.

Replies are listed 'Best First'.
Re^2: map split vs array split
by convenientstore (Pilgrim) on Jul 30, 2007 at 23:18 UTC
    Hi, I am running below and getting scalar value, I thought splitting up array into array would give me list context
    ~/script/perl/temp@myserver >cat perl.map2 #!/usr/bin/perl -w use strict; open (FH, 'foo.txt'); my @lines = <FH>; close FH; my @lines1 = split(' ', @lines); print "@lines1\n"; #hi how are you #i am fine ~/script/perl/temp@myserver >./perl.map2 2
      Yet again, it's all about context:

      my @lines1 = split(' ', @lines);

      split expects a regexp and a string as arguments, which are both scalars. @lines is evaluated in scalar context, returning the number of elements it contains. So, split has nothing to split, and returns the number of elements to be assigned to @lines1.

      Simply put, you can't split arrays. The purpose of split is to split a string into a list of values. Therefore, split expects a scalar as its second argument, representing the string to split. When you pass an array, the array is evaluated in scalar context, which returns the number of elements in the array.

      If you wanted to split each of the lines, you should use a foreach loop to iterate over the values in the array and operate on them one at a time:

      foreach (@lines) { my @lines1 = split(' ', $_); # $_ is "it" -- the current element of + @lines print @lines1,"\n"; }

      Or, for another approach, you could use map:

      map { print split(' ', $_),"\n" } @lines;

      In any case, split simply does not, will not work they way you're trying to use it -- it's not supposed to.

      Ramblings and references
      The Code that can be seen is not the true Code
      I haven't found a problem yet that can't be solved by a well-placed trebuchet

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2021-06-24 16:37 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (130 votes). Check out past polls.