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

I'm currently in the process of learning the ins and outs of regexes and for a learning curve, decided to use a code sub-pattern instead of the generic if-else construct with processing the given output. In this process, i encountered the error "panic: top_env" and compiled a quick report. I had trouble with the formatting on Perl Monks, and have created a quick pastebin with all the information i thought was relevant ( http://pastebin.com/m7debc55d ). Any information and advice on this problem will be very much appreciated, thanks monks!
  • Comment on Code Sub-Pattern Error "Panic: top_env"

Replies are listed 'Best First'.
Re: Code Sub-Pattern Error "Panic: top_env"
by desemondo (Hermit) on Dec 21, 2009 at 10:58 UTC

    FYI on Posting at Perlmonks in-a-nutshell; put your paragraphs inside <p></p> tags, and your code inside <code></code>. In your browser, select "view source" on this page and look at this post. It should show you (kind of...) the extra tags and their placement, which you can compare with what this post actually looks like. Also, you can preview your post as many times as you like until it looks right

    As you said yourself, the code you've written may be stupidly over-complicated... but I'm assuming you're posting here not because of the code itself, but because the code produces an apparent bug with the Perl interpreter...

    I found the debug switch use re qw{eval Debug ALL};, gives the extra output below:

    Compiling REx "(?(?{$_ =~ |$regex (\w+ \w+)(?=\1)|})(?{s|$1||})|(?{s|$ +1 \w+"... Starting first pass (sizing) >(?(?{$_ =~... | 1| reg | | brnc | | piec | | atom >?(?{$_ =~ ... | | reg >?{$_ =~ |$... | 2| reg >(?{s|$1||}... | 6| brnc | | piec | | atom >?{s|$1||})... | | reg >(?{s|$1 \w... | 12| brnc | | piec | | atom >?{s|$1 \w+... | | reg Required size 16 nodes Starting second pass (creation) >(?(?{$_ =~... | 1| reg | | brnc | | piec | | atom >?(?{$_ =~ ... | | reg >?{$_ =~ |$... | 2| reg panic: top_env C:\Temp\panic>
    And this is where i get stuck on where to go next with the investigation... perhaps another monk could shed further light?

    As you've noted from perldiag, a panic usually indicates a bug...
    Next steps would be to distill the REx down to the most simple form that produces the issue. Then checkout if its a known fault... (can another more enlightened monk comment on where and how faults with Perl can be queried?)
Re: Code Sub-Pattern Error "Panic: top_env"
by ww (Archbishop) on Dec 21, 2009 at 11:52 UTC

    Many here are reluctant to follow off-site links. Worse, such off-site postings are apt to be ephemeral... and don't make it into the Monastery db for future reference. Please see Markup in the Monastery, Perl Monks Approved HTML tags and What shortcuts can I use for linking to other information?.

    Having overcome my own reluctance, here's the pastebin content as you have it formatted:

    bash-3.1$ weather --weather Newcastle | ./regex.pl panic: top_env ====================================================================== +======= The output from (weather --weather Newcastle) the regex would be proce +ssing: ====================================================================== +======= bash-3.1$ weather --weather Newcastle Newcastle Light Rain Late Light Rain Late. Morning Clouds. Warm. ====================================================================== +======= ( regex.pl ) ====================================================================== +======= #!/usr/bin/perl -w use strict; my $regex = qr/\s* \w+/; while(<>) { use re 'eval'; /(?(?{$_ =~ |$regex (\w+ \w+)(?=\1)|})(?{s|$1||})|(?{s|$1 \w+| +|}))/; } ====================================================================== +========= Conclusion ====================================================================== +========= From what i can gather from lurking google, code sub-patterns are very + experimental and bug prone, ofcourse i could be wrong, seeing as i've only recently + adopted Perl in the last month once finishing my final year at school. From lurking google once more, i'm also gathering that the error messa +ge i'm receiving is a bug within perl itself, and should be reported. Bibliography: http://www.perlmonks.org/index.pl/?node_id=368099 http://prlmnks.org/html/383052.html

    It would be better, of course, to enclose (only) the code (by sections) in <c>...</c> tags and the narrative in <p>...</p> tags.

    Update: re desemondo's exploration,changing the use re... to use re qw(eval debug); and then testing via checking ( perl -c 813676.pl ) produced this for me (w2k, perl 5.8.8):

    Compiling REx `(?(?{$data =~ |$regex (\w+ \w+)(?=\1)|})(?{s|$1||})|(?{ +s|$1 \w+||}))' size 15 Got 124 bytes for offset annotations. panic: top_env
Re: Code Sub-Pattern Error "Panic: top_env"
by ikegami (Patriarch) on Dec 21, 2009 at 14:28 UTC

    urthwrm:

    /(?(?{$_ =~ |$regex (\w+ \w+)(?=\1)|})(?{s|$1||})|(?{s|$1 \w+||}))/

    perlre on (?{ }):

    Because Perl's regex engine is currently not re-entrant, interpolated code may not invoke the regex engine either directly with m// or s///), or indirectly with functions such as split.

    Additionally, changing the string against which you are matching when you're still matching against it is just asking for trouble.

Re: Code Sub-Pattern Error "Panic: top_env"
by ww (Archbishop) on Dec 21, 2009 at 20:39 UTC

    So, since the 'code sub-pattern' won't work ( see ikegami's++ above ) in the way you've attempted (and ++ for taking the challenging route), you may wish to reconsider your approach to the climb.

    If so, the following -- hidden in the readmore so as not to spoil the challenge you still face -- will work. Note, however, that I have assumed that the list of data returned by

    bash-3.1$ weather --weather Newcastle 009: Newcastle Light Rain Late Light Rain Late. Morning Clouds. War +m.

    represents a specific label ("Newcastle) followed by a set of possible alternatives

    So, without further ado:

      Sorry for the delay, I've been busy with university. I appreciate all the reply's, i have learned a lot. Anyway, i ended up taking the easy way out just to get things working. Here's my code for who ever might be interested!
      #!/usr/bin/perl -w use strict; while(<>) { if(m/\s*\ \w+ \ (\w+| \w+\ \w+| \w+\ \w+\ \w+) \ (?=\1)/x) { $_ =~ s/$1//; print; } }