Does split modify $_ ?

Discussion in 'Perl Misc' started by rebound@runbox.com, May 19, 2005.

  1. Guest

    Hi there,

    Please see this code:

    use strict;
    use warnings;

    open(IN, 'myfile.txt') or die "Open failed..$!\n";
    while(my @arr = split /:/, <IN>)
    {
    #print "* $_ *\n";
    if (/^#/) { print "Comment found\n"; }
    }
    close(IN);

    I attempted to read the filename (line-by-line), split it using ':' as
    seperator and stored the contents in an array. My IF check fails
    despite the file having only perl comments.
    $cat myfile.txt
    #Simple comment
    #another comment
    ##end

    I think that $_ is being set to undef by split.
    The split documentation does not say that $_ is modified by split.

    Can someone please explain why $_ is being modified here.

    TIA.
    Kasp
    , May 19, 2005
    #1
    1. Advertising

  2. writes:
    >
    > use strict;
    > use warnings;
    >
    > open(IN, 'myfile.txt') or die "Open failed..$!\n";
    > while(my @arr = split /:/, <IN>)
    > {
    > #print "* $_ *\n";
    > if (/^#/) { print "Comment found\n"; }
    > }
    > close(IN);
    >
    > I attempted to read the filename (line-by-line), split it using ':' as
    > seperator and stored the contents in an array. My IF check fails
    > despite the file having only perl comments.
    > $cat myfile.txt
    > #Simple comment
    > #another comment
    > ##end
    >
    > I think that $_ is being set to undef by split.
    > The split documentation does not say that $_ is modified by split.
    >
    > Can someone please explain why $_ is being modified here.


    $_ is not being modified by 'split'; it's in fact never set at all.
    You 'while' statement does not both iterate over the lines in the file
    and over the items in the split list; it only does the former. You need
    another iteration level in your code:

    while(my @arr = split /:/, <IN>) {
    for (@arr) {
    #print "* $_ *\n";
    if (/^#/) { print "Comment found\n"; }
    }
    }

    (There may be more to say about this code - I'm new myself - but this
    works.)

    It's the file you want to read, by the way, not the filename.

    I see that I'm assuming that your code was nearly correct already, but
    do you want '#' to start a comment within each ':'-delimited field, or
    only at the beginning of a line? The latter is more usual. If only at
    the beginning of a line, it doesn't make sense to check for that while
    iterating over the result of 'split'. I leave the necessary changes as
    an exercise.
    Arndt Jonasson, May 19, 2005
    #2
    1. Advertising

  3. Kasp Guest

    The <IN> in while loop will modify the $_ to contain the line read.

    You can try this:
    <IN>
    print $_; #or simply print;

    I don't understand why split sets $_ to undef...and how can I avoid
    doing so?

    Cheers
    Kasp

    --Posted via Google newsgroup...Sorry, folks.
    Kasp, May 19, 2005
    #3
  4. Anno Siegel Guest

    Kasp <> wrote in comp.lang.perl.misc:

    > The <IN> in while loop will modify the $_ to contain the line read.
    >
    > You can try this:
    > <IN>
    > print $_; #or simply print;


    Did *you* try this?

    A lone <$IN> does *not* set $_ to anything. You are working on wrong
    assumptions. Read up on "while" in perlsyn to see when it does what
    to $_.

    > I don't understand why split sets $_ to undef...and how can I avoid
    > doing so?


    Split has nothing to do with it, $_ has never been set.

    Anno
    Anno Siegel, May 19, 2005
    #4
  5. Joe Smith Guest

    Kasp wrote:
    > The <IN> in while loop will modify the $_ to contain the line read.


    For a simple while() conditional, yes.
    For a nontrivial while() conditional, no.

    while(<IN>){} is the same as while(defined($_=<IN>)){};
    while(something <IN>){} is not the same; $_ is *NOT* set.

    > You can try this:
    > <IN>
    > print $_; #or simply print;


    Oh, really? Did you actually try it?
    $_ = 'original unchanged value';
    <IN>;
    print $_;
    will not put a line of input into $_.

    > I don't understand why split sets $_ to undef...and how can I avoid
    > doing so?


    If you never put anything into $_, then of course it remains undef.
    You avoid this by writing code that actually puts data into $_.

    -Joe
    Joe Smith, May 20, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    451
  2. Carlos Ribeiro
    Replies:
    11
    Views:
    684
    Alex Martelli
    Sep 17, 2004
  3. trans.  (T. Onoma)

    split on '' (and another for split -1)

    trans. (T. Onoma), Dec 27, 2004, in forum: Ruby
    Replies:
    10
    Views:
    202
    Florian Gross
    Dec 28, 2004
  4. Sam Kong
    Replies:
    5
    Views:
    227
    Rick DeNatale
    Aug 12, 2006
  5. Stanley Xu
    Replies:
    2
    Views:
    582
    Stanley Xu
    Mar 23, 2011
Loading...

Share This Page