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

Re: Views on changing Math-BigInt OO design

Thread Previous | Thread Next
Aristotle Pagaltzis
October 8, 2015 00:10
Re: Views on changing Math-BigInt OO design
Message ID:
* Peter John Acklam <> [2015-10-07 15:45]:
> Even my soon 20 year old version of The Camel Book does not mention
> this syntax, so I doubt it is much used anymore, but there could
> stille be some old code that will break if this syntax no longer
> works. spots Dev::Bollocks.

All other hits are false positives, as far as I can see.

> In essence, if I go on with my idea, Math::BigInt::badd(3, 5) will
> have to be written as Math::BigInt -> badd(3, 5). Is that such a big
> problem that I should leave the code as it is?

I’d say you should not break such code without a deprecation cycle. You
can do something like

    package Math::BigInt;
    use Carp ();
    for my $fn ( qw( badd bsub bmult betc betc betc ) ) {
        my $glob = do { no strict 'refs'; \*$fn };
        *$glob = sub {
            Carp::carp "deprecated non-OO call to $fn blah blah" if @_ == 2;
            local *$glob; # magic
            unshift @_, __PACKAGE__; # deception
            goto &{ __PACKAGE__->can( $fn ) }; # smoke and mirrors

This adds subs to the package for all the potentially directly called
slots; “magic” makes the sub temporarily hide from the method call
lookup performed by ->can(), “deception” adds an invocant to @_ to make
it look as though it always had been a method call, and finally the
“smoke and mirrors” goto removes the stack frame for this call while
completing the illusion.

Note that this is *slow*. You might want to give users a way to tell you
not to bother with these, maybe by way of an import option, or maybe by
way of an env var. The point of writing it this way is to encapsulate
the deprecation code cleanly. This makes the deprecation code very easy
to remove. More importantly it allows writing as well as testing the
rest of the code as though this crutch weren’t there, which minimises
the chances that the behaviour of the other code will change when you
drop the deprecation, which would affect users who have done the right
thing and written to the recommended interface.

You’d keep this in there for a year or two until all users have had due
notice, then you can drop it on the floor after enough time has passed.
(Probably a short cycle is OK for this, if it has as little use in the
wild as it appears to.)

Note that I’m not claiming my sample code is the right way or the best
way of doing this; I just came up with it off the top of my head. I’m
just trying to illustrate the kind of thinking that goes into this.

Backcompat is hard work, let’s go shopping.

Aristotle Pagaltzis // <>

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About