Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: Splitting in while loop

by tel2 (Pilgrim)
on Oct 07, 2021 at 05:16 UTC ( [id://11137289]=note: print w/replies, xml ) Need Help??


in reply to Re: Splitting in while loop
in thread Splitting in while loop

Nice work, thanks for both your solutions, tybalt89!

Do you understand why mine wasn't working?

Replies are listed 'Best First'.
Re^3: Splitting in while loop
by kcott (Archbishop) on Oct 07, 2021 at 07:43 UTC

    G'day tel2,

    "... why mine wasn't working?"

    I believe you're working on the erroneous assumption that split(/[, ]+/, <DATA>) will assign its result to $_. That assignment to $_ only occurs in a select number of cases. From "perlsyn: Compound Statements":

    "If the condition expression of a while statement is based on any of a group of iterative expression types then it gets some magic treatment. The affected iterative expression types are readline, the <FILEHANDLE> input operator, ... If the condition expression is one of these expression types, then the value yielded by the iterative operator will be implicitly assigned to $_."

    For each of your while iterations, the condition is true three times, once for each DATA line; however, $_ is not set for any of those iterations. On the fourth iteration, there are no more DATA lines and the loop ends.

    Always add

    use strict; use warnings;

    to the top of your code. In this instance, although it wouldn't give a detailed explanation of the problem as I've provided, it would have hinted at a starting point for investigating the issue.

    — Ken

      Thanks for all that, Ken.

      I tried adding strict & warnings before opening this question, and I got the errors, but I just didn't realise what was going on, but I understand now.  Maybe I should have posted it with strict & warnings included, and asked why I'm getting the errors.

        "Maybe I should have posted it with strict & warnings included, and asked why I'm getting the errors."

        I concur with ++eyepopslikeamosquito's comments: that would have been a far better way to deal with this.

        Removing those pragmata from your code does not remove whatever problem they reported. This is basically just putting your head in the sand: it neither helps you nor helps us to help you.

        What you can do is look for the exception message in perldiag. Admittedly, in this instance, the description for "Use of uninitialized value %s" will not be all that helpful, unless you really don't understand that message: but, as I said earlier, "it would have hinted at a starting point for investigating the issue". In many cases, however, the expanded explanation in perldiag can be quite enlightening.

        Another option you have is to use the diagnostics pragma. Be aware that this can be somewhat overwhelming and leave you feeling that you're drowning in exception output. You can get multiple, often large, blocks of text; however, just as a simple example, consider a typo where you didn't release the shift key quickly enough after typing a " and ended up typing a : instead of a ; as the next character:

        $ perl -Mstrict -Mwarnings -Mdiagnostics -e 'my $x = "X": print "$x\n" +;' syntax error at -e line 1, near ""X":" Execution of -e aborted due to compilation errors (#1) (F) Probably means you had a syntax error. Common reasons include +: A keyword is misspelled. A semicolon is missing. A comma is missing. An opening or closing parenthesis is missing. An opening or closing brace is missing. A closing quote is missing. Often there will be another error message associated with the synt +ax error giving more information. (Sometimes it helps to turn on -w. +) The error message itself often tells you where it was in the line +when it decided to give up. Sometimes the actual error is several toke +ns before this, because Perl is good at understanding random input. Occasionally the line number may be misleading, and once in a blue + moon the only way to figure out what's triggering the error is to call perl -c repeatedly, chopping away half the program each time to se +e if the error went away. Sort of the cybernetic version of 20 ques +tions. Uncaught exception from user code: syntax error at -e line 1, near ""X":" Execution of -e aborted due to compilation errors.

        Also note that the diagnostics pragma is a developer tool; it is not (normally) appropriate for production code. Remove use diagnostics; (and similar code) when moving from the development to the production environments.

        — Ken

        > Maybe I should have posted it with strict & warnings included, and asked why I'm getting the errors

        Yes!

        Even more important, read and understand the basic Perl documentation for the functions you are using. If your program does not behave the way the Perl documentation says it should, mention that in your question. For example, the Perl documentation for split says this, yet I am seeing that. (Based on your question, I don't see how you could have read and understood the documentation for split).

        In summary, please read and attempt to understand the Perl documentation and test your code with strict and warnings before posting.

Re^3: Splitting in while loop
by AnomalousMonk (Archbishop) on Oct 07, 2021 at 07:44 UTC

    Further to jwkrahn's post:   tel2: Note that implicit split to @_ has been deprecated for a long time:

    Win8 Strawberry 5.8.9.5 (32) Thu 10/07/2021 3:29:50 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings my $data = <<'EOD'; me@here.com those@there.com others@there.com you@there.com,them@there.com EOD open my $fh, '<', \$data or die "opening: $!"; while (split(/[, ]+/, <$fh>)) { chomp @_; print "'$_'\n" for @_; } ^Z Use of implicit split to @_ is deprecated at - line 14. 'me@here.com' 'those@there.com' 'others@there.com' 'you@there.com' 'them@there.com'


    Give a man a fish:  <%-{-{-{-<

Re^3: Splitting in while loop
by AnomalousMonk (Archbishop) on Oct 07, 2021 at 07:21 UTC
    while (split(/[, ]+/, <DATA>)) { ... }

    Only a while-loop condition expression like

    while (<DATA>) { ... }
    assigns implicitly to $_ (see tybalt89's example) (update: but see kcott's post for a more complete discussion of $_ assignment special-casing). An arbitrary expression like split(...) does not. Had you had warnings enabled, Perl would have at least hinted at this problem.


    Give a man a fish:  <%-{-{-{-<

Re^3: Splitting in while loop
by jwkrahn (Abbot) on Oct 07, 2021 at 07:21 UTC
    while (split(/[, ]+/, <DATA>))

    Is interpreted by perl as:

    while ( @_ = split( /[, ]+/, <DATA> ) )
      Thanks jwkrahn, but if they're interpreted to be the same, then why does this code:
      while (split(/[, ]+/, <DATA>)) { print @_ }
      print nothing, while this code:
      #while (split(/[, ]+/, <DATA>)) # Edit: Sorry - ignore this while (@_ = split(/[, ]+/, <DATA>)) # Edit: I meant this { print @_ }
      prints:
      me@here.com those@there.comothers@there.com you@there.comthem@there.com
      ?

      Update: Cancel the above.  I see AnomalousMonk's answer to it now.

        If you just print an array (as in print @_) there will be nothing to show where each element starts and ends:

        $ perl -e '@_ = qw{a bcd ef}; print @_' abcdef

        If you put the array in interpolating quotes, you will see each element separated by the value of the special variable $" (which, by default, is a space):

        $ perl -e '@_ = qw{a bcd ef}; print "@_"' a bcd ef $ perl -e '@_ = qw{a bcd ef}; print qq{@_}' a bcd ef

        In rare situations, perhaps where $" was changed elsewhere in the code, you may want to make a localised change to $" (typically within an anonymous block). See local, "Temporary Values via local()" and "Localization of special variables" for more details on that. Some examples:

        $ perl -e '@_ = qw{a bcd ef}; { local $" = " "; print "@_" }' a bcd ef $ perl -e '@_ = qw{a bcd ef}; { local $" = "__"; print "@_" }' a__bcd__ef $ perl -e '@_ = qw{a bcd ef}; { local $" = "\n"; print "@_" }' a bcd ef

        — Ken

Log In?
Username:
Password:

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

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

    No recent polls found