Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Continue block entry

by prowler (Friar)
on May 10, 2005 at 05:33 UTC ( [id://455440]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there

I've currently got a bit of a problem that I'm trying to debug, but the actual problem isn't that important. The relevant section is a foreach block with an associated continue block, and a few different ways in which the current iteration of the loop can be found lacking, and have 'next' called.

Anyway, the question is: is there anyway to tell within a continue block how it was reached (ie whether it was reached through falling off the associated loop block, or via a 'next', and if possible, which line had the offending 'next' on it).

I'm not sure that this would be useful in production code, but for debugging it could be helpful to let me know why the loop isn't achieving anything. Yes, I could go through the loop and have warnings everywhere (and may have to if the information I want is not obtainable), but if I could just have a single line that lets me know where my logic decides to jump out of the loop I'd be able to track down the problem a whole lot quicker

Thanks

Prowler
 - Spelling is a demanding task that requies you full attention.

Replies are listed 'Best First'.
Re: Continue block entry
by Zaxo (Archbishop) on May 10, 2005 at 05:47 UTC

    I don't know of any inherent property you could check to see if next had fired. You could set a flag on entry and clear it at the end of the loop block:

    my $next_flag; for (@foo) { $next_flag = 1; # my $next_flag = 1; # scope problem # do stuff $next_flag = 0; } continue { warn 'nexted!' if $next_flag; # go on }

    Update: Thanks, ikegami, repaired.

    After Compline,
    Zaxo

      Thanks to both of you for the suggestions, I kind of figured that was likely to be the case, but I was hoping there would be some existing function (or magicly accessible values) with similar information to that provided by caller.

      Prowler
       - Spelling is a demanding task that requies you full attention.

        Perl has an odd feature that you can next out of a block from within a subroutine. Ie:

        sub mynext { next } for (1..10) { mynext(); print $_; }

        This usage will warn as its a form of action at a distance, but it is legal and can be useful*. Thus you could put some caller-fu in mynext() and have it warn where it was called. This would require temporarily s/next/mynext()/g of course so IMO its not a route to be taken lightly. OTOH if its this type of stuff that is causing your problem in the first place then warnings will reveal all. You didnt show any code so its hard to say. :-)

        * An interesting example is its usage in the Test framework for handling SKIP blocks

        ---
        $world=~s/war/peace/g

      You need to remove the my for that code to work.
Re: Continue block entry
by ikegami (Patriarch) on May 10, 2005 at 05:44 UTC

    This is probably minimal:

    foreach (@array) { $fall_through = 0; ... $fall_through = 1; } continue { print($fall_through ? "Fell" : "Didn't fall", " through.\n"); ... }
Re: Continue block entry
by Gilimanjaro (Hermit) on May 10, 2005 at 09:36 UTC

    Sound like you may want to use eval for this, and die instead of next:

    foreach (@a) { eval { die 'reason1' if check_condition1(); do_some_stuff(); die 'reason2' if check_condition2(); do_more_stuff(); die 'reason3' if check_condition3(); play_solitaire(); do_something_if_all_ok(); }; # a *real* error, if it doesn't start with 'reason' die if $@ && $@ !~ /^reason/; # save reason; you never know what other evals happen my $reason = $@; # usual continue code here do_something_always(); if($reason) { only_if_reason1() if $@ eq 'reason1' } }

    You may want to die with an object of some kind, to easily distinguish between 'real' error, and your type of conditions.

    Update: corrected the die regex to Do The Right Thang

      Thanks for the suggestion, but I assume you mean:

      die if $@ && $@ !~ /^reason/

      rather than '=~'.

      Prowler
       - Spelling is a demanding task that requies you full attention.

        yup. sorry. will update now...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://455440]
Approved by ikegami
Front-paged by wfsp
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (8)
As of 2024-04-19 13:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found