Subject: | Type::Library::_mksub generates a new sub when importing types from another library |
My apologies if the subject line is a bit unclear.
The fundamental issue I'm running into is that the "factory" sub made
available by a type library is regenerated by any libraries that
inherit from it.
Here's more background on what I'm trying to accomplish.
I'm cleaning up several nested type libraries and would like to
deprecate some of the types. I'd like for the deprecated types to
issue a warning when the (for better name) "factory" sub which returns
the type is run (rather than each time type verification is
performed), so I thought that wrapping the "factory" sub created by
Type::Library::_mksub would be the least intrusive method of doing so:
package Type::Library::Role::Deprecate;
use Scalar::Util ();
use Role::Tiny;
around '_mksub' => sub {
my $orig = shift;
my ( $class, $type ) = @_;
my $sub = $orig->( @_ );
return $sub unless $class->meta->{deprecated}{ $type->qualified_name };
return sub {
warn( $type->qualified_name . " is deprecated\n" );
&$sub;
}
};
sub deprecate {
my $meta = shift->meta;
my $class = Scalar::Util::blessed( $meta );
$meta->{deprecated}{"$class\::$_"} = 1 for @_;
}
1;
In my base type library:
use Type::Library
-base,
-declare => qw(
ChanType
ChanSpec
EnUnit
EnSpec
);
use Role::Tiny::With;
with 'Type::Library::Role::Deprecate';
__PACKAGE__->deprecate( qw[ ChanType ChanSpec EnUnit EnSpec ] );
However, when another library extends mine (e.g. via
Type::Utils::extends), Type::Library::add_type calls
Type::Library::_mksub, which regenerates the "factory" sub using an unwrapped
_mksub, and the deprecation notice isn't added.
I'm ignorant of the reasons for not caching _mksub's results. It would
make things like the above possible. Or, perhaps I'm going about this
the wrong way.
Thanks in advance.
Diab