Working around a lack of Scalar::Util::refaddr with AS Perl

Ovid on 2006-12-02T10:56:53

I was all ready to use the following bit of code in one of my modules to let it build properly with ActivePerl:

use Scalar::Util;

BEGIN {
    if ( defined &Scalar::Util::refaddr ) {
        *_ident = \&Scalar::Util::refaddr;
    }
    else {
        require overload;
        *_ident = sub {
            my ( $object ) = @_;
            if ( overload::Method($object, '""') ) {
                croak "Overloaded stringification requires &Scalar::Util::refaddr (version 1.08 or greater)";
            }
            return "$object";
        };
    }
}

Then I double-checked and saw that refaddr is a pure Perl function. Regrettably, I copied it into my code:

sub _refaddr($) {
    my $pkg = ref( $_[0] ) or return undef;
    if ( blessed( $_[0] ) ) {
        bless $_[0], 'Class::BuildMethods::Fake';
    }
    else {
        $pkg = undef;
    }
    "$_[0]" =~ /0x(\w+)/;
    my $i = do { local $^W; hex $1 };
    bless $_[0], $pkg if defined $pkg;
    $i;
}

This raises an interesting, but ugly, question. What about a module which provides functionality which core modules have, but only in upgraded versions which AS does not provide? For example:

use Module::Substitute 
    'Scalar::Util' => [qw/refaddr openhandle/];

That's a terrible name, but this would be something designed to not go into core, thus allowing people to use these extra functions if they want to build on ActiveState. I really hate the idea of duplicating this code, but this might be a way to get around some of the AS build problems.


One at a time, possibly?

Alias on 2006-12-02T15:41:07

One of the problems that might happen with a Module::Substitute is that implementation for THAT gets as bad as for others.

I'd like to see special-purpose single function modules.

i.e. Scalar::Refaddr etc etc