Like Zaxo, I was able to run the code unmodified, on 5.8.5 built for i386-freebsd-64int, but when I tried it with 5.8.1 on macosx (built for darwin-thread-multi-2level), I got the behavior you cited.

When I tried stepping through it with "perl -d" on the mac, I found that at some point within the regex-eval code, it got completely lost and went into something that strongly resembled a tight infinite loop (chewed up tons of cpu, and couldn't be stopped with "^C") -- I had to go to another shell, look up the pid for the "perl -d" job, and kill it.

Interestingly, when I tried stepping through it with the debugger in 5.8.5 freebsd, it went fine up to a point: it output "12: 3 is better than 0", went a couple more steps, then died with:

Out of memory during ridiculously large request at 438502.pl line 17.

Presumably, my line numbers might not match yours -- 17 is the start of the "if (..." that contains that truly bizarre regex containing a whole subroutine worth of executable code as part of a match operation.

So what's really strange, beyond the fact that "older" builds can't run this code at all, is that a relatively new build will blow up only if you run the code in debug mode.

Patient: Doc, it really hurts every time I do this.

Doctor: Well, don't do that.

Really, why put all that code into the regex? Even in the 5.8.5 "perlre" manual, the description of the "(?{code})" feature starts with:

WARNING: This extended regular expression feature is considered highly experimental, and may be changed or deleted without notice.
If you really can't resist "playing with matches", then at the very least, simplify the regex to an actual subroutine call, and put all that code into a sub. Maybe it won't change what perl utlimately does when faced with your experimental code, but it'll make it easier for you to refactor the code into something that makes sense (and actually runs).

BIG UPDATE: So I tried this advice myself, and rewrote the code as follows:

use strict; use warnings; use re 'eval'; my @denoms = (10, 6, 5, 1); my $expr = join '', map "((?:$_)*)", map '1' x $_, @denoms; print "E=$expr\n"; sub greedy_change { my $change = shift; my $coin_count = 0; my @combo; $_ = ('1' x $change); print "Trying to change $change with @denoms...\n"; print "$expr on $_\n"; if ( m{^$expr$ (?{&regex_sub( \$coin_count, \$change, \@combo )}) }x) { print "Matched!\n"; } if ($coin_count) { print "C=$coin_count\n"; } else { print "No matching combination found\n"; } @combo; } for my $num (12, 14, 36) { my @change = greedy_change($num); print "$num: @change\n"; } sub regex_sub { my ($coin_count,$change,$combo) = @_; print "Code doesn't get run after once.\n"; my @lengths = ($+[1]); my $new_count = 0; $lengths[$_] = $+[$_+1] - $+[$_] for 1..$#denoms; $new_count += $lengths[$_]/$denoms[$_] for 0..$#denoms; if (!$$coin_count or $new_count < $$coin_count) { print "$$change: $new_count is better than $$coin_count\n"; $$coin_count = $new_count; @$combo = @lengths; } }

Three very interesting discoveries: First, when stepping through your original code with any version of debugger, I was never able to inspect the values of variables that were lexically scoped within the regex code (i.e. "my @lengths, my $new_count" were not accessible for inspection in the debugger); when I put the code into a sub, this problem went away, and I was able to check these variables as I stepped along.

Second, with the regex code block separated into a sub, the script behaved the same on 5.8.1 darwin as it did on 5.8.5 freebsd -- that is, it ran and did not die. (Whether it actually produced output that you would consider "correct and intended" is another question, and I have doubts about that.)

Third, I saw some striking evidence to indicate why this new regex/eval feature is considered experimental, and why it should not be trusted yet. Consider the following snippet from the debugging session:

... DB<1> s main::regex_sub(438502.pl:40): print "Code doesn't get run after +once.\n"; DB<1> s Code doesn't get run after once. main::regex_sub(438502.pl:41): my @lengths = ($+[1]); DB<1> p scalar @+ 5 DB<2> p join ":",@+ 12:10:10:10:12 DB<3> s main::regex_sub(438502.pl:42): my $new_count = 0; DB<3> p @lengths 10 DB<4> p join ":",@+ 23:22:23
Like, WHOA! What's up with that? I can't begin to guess. I'd stop right there and try a completely different approach that avoids the experimental feature.

(One more update: I fixed a misspelling in the "(?{...})" subroutine call (initially had "$coing_count" as first parameter). Since it was in an eval-like block, it wasn't caught by "strict". Also, I found that the odd behavior of @+ in the debugger was not related to any particular step in the code -- it's simply an issue of getting one result the first time you inspect @+ within the eval block, and getting a different result the second time:

main::regex_sub(438502.pl:40): print "Code doesn't get run after +once.\n"; DB<1> s Code doesn't get run after once. main::regex_sub(438502.pl:41): my @lengths = ($+[1]); DB<1> p scalar @+ 5 DB<2> p scalar @+ 3
Just the fact that it's hard to debug this approach makes me feel strongly about choosing a different approach.)

In reply to Re: Undefined value as array reference by graff
in thread Undefined value as array reference by Roy Johnson

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.