my %warned;
return sub {
+ my %args = @_ < 2 ? ( message => shift ) : @_;
+
my ( $package, undef, undef, $sub ) = caller(1);
+ unless ( defined $args{feature} ) {
+ $args{feature} = $sub;
+ }
+
my $compat_version = $registry->{$package};
- my $deprecated_at = $deprecated_at->{$sub};
+ my $deprecated_at = $deprecated_at->{ $args{feature} };
return
if defined $compat_version
&& defined $deprecated_at
&& $compat_version lt $deprecated_at;
- return if $warned{$package}{$sub};
+ return if $warned{$package}{ $args{feature} };
- if ( ! @_ ) {
- my $msg = "$sub has been deprecated";
+ if ( defined $args{message} ) {
+ @_ = $args{message};
+ }
+ else {
+ my $msg = "$args{feature} has been deprecated";
$msg .= " since version $deprecated_at"
if defined $deprecated_at;
@_ = $msg;
}
- $warned{$package}{$sub} = 1;
+ $warned{$package}{ $args{feature} } = 1;
goto &Carp::cluck;
};
package My::Class;
- use Package::DeprecationManager
- -deprecations => {
- 'My::Class::foo' => '0.02',
- 'My::Class::bar' => '0.05',
- };
+ use Package::DeprecationManager -deprecations => {
+ 'My::Class::foo' => '0.02',
+ 'My::Class::bar' => '0.05',
+ 'feature-X' => '0.07',
+ };
sub foo {
deprecated( 'Do not call foo!' );
...
}
+ sub baz {
+ my %args = @_;
+
+ if ( $args{foo} ) {
+ deprecated(
+ message => ...,
+ feature => 'feature-X',
+ );
+ }
+ }
+
package Other::Class;
use My::Class -api_version => '0.04';
This module allows you to manage a set of deprecations for one or more modules.
When you import C<Package::DeprecationManager>, you must provide a set of
-C<-deprecations> as a hash ref. The keys are fully qualified sub/method names,
-and the values are the version when that subroutine was deprecated.
+C<-deprecations> as a hash ref. The keys are "feature" names, and the values
+are the version when that feature was deprecated.
+
+In many cases, you can simply use the fully qualified name of a subroutine or
+method as the feature name. This works for cases where the whole subroutine is
+deprecated. However, the feature names can be any string. This is useful if
+you don't want to deprecate an entire subroutine, just a certain usage.
As part of the import process, C<Package::DeprecationManager> will export two
subroutines into its caller. It proves an C<import()> sub for the caller and a
deprecations for api versions earlier than the one specified.
You must call C<deprecated()> sub in each deprecated subroutine. When called,
-it will issue a warning using C<Carp::cluck()>. If you do not pass an explicit
-warning message, one will be generated for you.
+it will issue a warning using C<Carp::cluck()>.
+
+The C<deprecated()> sub can be called in several ways. If you do not pass any
+arguments, it will generate an appropriate warning message. If you pass a
+single argument, this is used as the warning message.
+
+Finally, you can call it with named arguments. Currently, the only allowed
+names are C<message> and C<feature>. The C<feature> argument should correspond
+to the feature name passed in the C<-deprecations> hash.
+
+If you don't explicitly specify a feature, the C<deprecated()> sub uses
+C<caller()> to identify its caller, using its fully qualified subroutine name.
Deprecation warnings are only issued once for a given package, regardless of
how many times the deprecated sub/method is called.