UNIVERSAL::ref - Turns ref() into a multimethod
Contents
Acknowledgements
ambrus for the excellent idea to overload defined() to allow Perl 5 to have Perl 6's "interesting values
of undef."
chromatic for pointing out how utterly broken ref() is. This fix covers its biggest hole.
Description
This module changes the behavior of the builtin function ref(). If ref() is called on an object that has
requested an overloaded ref, the object's "->ref" method will be called and its return value used
instead.
License
The standard Artistic / GPL license most other perl code is typically using.
perl v5.40.1 2025-04-15 UNIVERSAL::ref(3pm)
Methods
import
A pragma for ref()-enabling your class. This adds the calling class name to a global list of
ref()-enabled classes.
package YourClass;
use UNIVERSAL::ref;
sub ref { ... }
unimport
A pragma for ref()-disabling your class. This removes the calling class name from a global list of
ref()-enabled classes.
Name
UNIVERSAL::ref - Turns ref() into a multimethod
Synopsis
# True! Wrapper pretends to be Thing.
ref( Wrapper->new( Thing->new ) )
eq ref( Thing->new );
package Thing;
sub new { bless [], shift }
package Wrapper;
sub new {
my ($class,$proxy) = @_;
bless \ $proxy, $class;
}
sub ref {
my $self = shift @_;
return $$self;
}
Todo
Currently UNIVERSAL::ref must be installed before any ref() calls that are to be affected.
I think ref() always occurs in an implicit scalar context. There is no accomodation for list context.
UNIVERSAL::ref probably shouldn't allow a module to lie to itself. Or should it?
Using
To enable this feature for a class, "use UNIVERSAL::ref" in your class. Here is a sample proxy module.
package Pirate;
# Pirate pretends to be a Privateer
use UNIVERSAL::ref;
sub new { bless {}, shift }
sub ref { return 'Privateer' }
Anywhere you call ref($obj) on a "Pirate" object, it will allow "Pirate" to lie and pretend to be
something else.
