Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange error message with anon subroutine

6 views
Skip to first unread message

Ovid

unread,
Dec 13, 2006, 2:31:33 PM12/13/06
to perl6...@perl.org
In trying to compress a list, I wrote the following code:

my $compress = do {
my $previous;
$compress = -> $x {
if !defined $previous or $x ne $previous {
$previous = $x;
$x;
}
else {
();
}
};
}
my @compressed = map $compress, <a a a a b c c a a d e e e e>;
@compressed.say;

That's a bit more verbose than I intended, but that's partially because
of this:

my $compress = do {
my $previous;
$compress = -> $x {
if !defined $previous or $x ne $previous {
$previous = $x;
return $x;
}
else {
return ();
}
};
};

As soon as I put the return statements in an anonymous subroutine, I
get this error message:

*** Cannot use this control structure outside a 'routine' structure
at 99.pugs line 103, column 13-22

Take out the returns, and it works fine. Can someone tell me what I'm
missing? Is this a bug.

Also, I noticed I accidentally left off the final semi-colon on the do
block. It ran anyway and that surprised me.

Cleaner ways of writing that code are welcome, too.

Cheers,
Ovid

--

Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/

Larry Wall

unread,
Dec 13, 2006, 3:00:06 PM12/13/06
to perl6...@perl.org
On Wed, Dec 13, 2006 at 11:31:33AM -0800, Ovid wrote:
: In trying to compress a list, I wrote the following code:

Nope, spec. S06 says:

[Pointy block] also behaves like a block with respect to control
exceptions. If you C<return> from within a pointy block, it will
return from the innermost enclosing C<sub> or C<method>, not the
block itself. It is referenced by C<&?BLOCK>, not C<&?ROUTINE>.

See also the section in S04 discussing control exceptions, where it says:

A C<return> always exits from the lexically surrounding sub
or method definition (that is, from a function officially declared
with the C<sub>, C<method>, or C<submethod> keywords). Pointy blocks
and bare closures are transparent to C<return>.

So all you really need to do is change the pointy to an official sub:

my $compress = do {
my $previous;

$compress = sub ($x) {


if !defined $previous or $x ne $previous {
$previous = $x;
return $x;
}
else {
return ();
}
}
}

: Also, I noticed I accidentally left off the final semi-colon on the do


: block. It ran anyway and that surprised me.

S04:

Outside of any kind of expression brackets, a final closing curly
on a line (not counting whitespace or comments) always reverts
to the precedence of semicolon whether or not you put a semicolon
after it.

Larry

Gaal Yahas

unread,
Dec 13, 2006, 3:19:54 PM12/13/06
to Ovid, perl6...@perl.org
On Wed, Dec 13, 2006 at 11:31:33AM -0800, Ovid wrote:
> *** Cannot use this control structure outside a 'routine' structure
> at 99.pugs line 103, column 13-22
>
> Take out the returns, and it works fine. Can someone tell me what I'm
> missing? Is this a bug.

Perl 6 differentiates between a bare Code and Routine objects. Replacing
"->" with "sub" should get you what you want.

--
Gaal Yahas <ga...@forum2.org>
http://gaal.livejournal.com/

0 new messages