UNIVERSAL::ref3pm
Turns ref() into a multimethod
Usage
# 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;}
Overview
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.
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 Privateeruse 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.
Methods
- import
-
A pragma for
ref()-enabling your class. This adds the calling class name to a global list ofref()-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 ofref()-enabled classes.
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?
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.
Releases
5 releases since Debian 9 (Stretch); the text changed 4 times.