develooper Front page | perl.perl5.porters | Postings from October 2005

The "redefined sort subs" business

Thread Next
From:
Robin Houston
Date:
October 24, 2005 14:22
Subject:
The "redefined sort subs" business
Message ID:
20051024212139.GA13008@rpc142.cs.man.ac.uk
I've started to implement the idea we discussed, and it seems to be
working as expected, though I need to do more testing.

I'd love to know more about the rationale behind the "Can't redefine
active sort sub" thing. The original implementation is here:

 http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1997-05/msg00707.html

where Sarathy wrote:
> Chip Salzenberg identified the metaconfig problem private mail thusly:
> >
> >sub sortfunc { &once }
> >sub once {
> >    eval q{
> >       print "Eval from ", join(':', caller(0)), "\n";
> >       sub rest {
> >           print "REST: $a <=> $b\n";
> >           $a <=> $b
> >       }
> >    };
> >    *sortfunc = *rest;
> >    &sortfunc;
> >}
> >@x = sort sortfunc 10, 5, 2.5, 1.25;
> 
> That misbehaves due to the redefinition of the sort sub
> while the sort is active.  That's a big no-no, because
> the sortcop was pointing to the CvSTART of the original,
> and it will now point to freed memory (if the sub really
> got undefined).

I'd be interested to know exactly how it misbehaved. The sort
sub won't really get undefined until the sort has finished, because
its refcount is incremented by the PUSHSUB that pp_sort() does.
If you remove the code that prevents sort subs from being redefined,
everything seems to work as you'd expect, without causing any
problems.

Incidentally, there's a bug in the current implementation. The
PUSHSUB has no matching LEAVESUB, which means that the refcount
of the sub is *permanently* incremented. For example:
 
$ perl -MDevel::Peek -e 'sub foo {1} Dump\&foo; @r=sort foo 1,2; Dump
\&foo; @r=sort foo 1,2; Dump \&foo' 2>&1 | egrep '^    REFCNT'
    REFCNT = 2
    REFCNT = 3
    REFCNT = 4

The same bug is also present in List::Util.

Given how apparently difficult it is to get this right, the
idea of having standard macros for it seems ever more appealing.
I'm thinking of calling the macros *MULTICALL*, on the grounds
that this idiom is used for repeatedly calling the same sub.
Does anyone object to that name?

Robin

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About