Skip to content

Commit

Permalink
Disallow importing functions from UNIVERSAL
Browse files Browse the repository at this point in the history
It's been deprecated since v5.12.
  • Loading branch information
ilmari authored and tonycoz committed Jul 21, 2014
1 parent e81c4bd commit 1178d2c
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 49 deletions.
29 changes: 8 additions & 21 deletions lib/UNIVERSAL.pm
@@ -1,27 +1,18 @@
package UNIVERSAL;

our $VERSION = '1.11';
our $VERSION = '1.12';

# UNIVERSAL should not contain any extra subs/methods beyond those
# that it exists to define. The use of Exporter below is a historical
# accident that can't be fixed without breaking code. Note that we
# *don't* set @ISA here, as we don't want all classes/objects inheriting from
# Exporter. It's bad enough that all classes have a import() method
# whenever UNIVERSAL.pm is loaded.
require Exporter;
@EXPORT_OK = qw(isa can VERSION);
# that it exists to define. The existence of import() below is a historical
# accident that can't be fixed without breaking code.

# Make sure that even though the import method is called, it doesn't do
# anything unless called on UNIVERSAL.
sub import {
return unless $_[0] eq __PACKAGE__;
return unless @_ > 1;
require warnings;
warnings::warnif(
'deprecated',
'UNIVERSAL->import is deprecated and will be removed in a future perl',
);
goto &Exporter::import;
require Carp;
Carp::croak("UNIVERSAL does not export anything");
}

1;
Expand Down Expand Up @@ -190,21 +181,17 @@ available to your program (and you should not do so).
=head1 EXPORTS
None by default.
None.
You may request the import of three functions (C<isa>, C<can>, and C<VERSION>),
B<but this feature is deprecated and will be removed>. Please don't do this in
new code.
For example, previous versions of this documentation suggested using C<isa> as
Previous versions of this documentation suggested using C<isa> as
a function to determine the type of a reference:
use UNIVERSAL 'isa';
$yes = isa $h, "HASH";
$yes = isa "Foo", "Bar";
The problem is that this code will I<never> call an overridden C<isa> method in
The problem is that this code would I<never> call an overridden C<isa> method in
any class. Instead, use C<reftype> from L<Scalar::Util> for the first case:
use Scalar::Util 'reftype';
Expand Down
6 changes: 6 additions & 0 deletions pod/perldelta.pod
Expand Up @@ -45,6 +45,12 @@ XXX For a release on a stable branch, this section aspires to be:

[ List each incompatible change as a =head2 entry ]

=head2 S<C<use UNIVERSAL '...'>> is now a fatal error

Importing functions from C<UNIVERSAL> has been deprecated since v5.12, and
is now a fatal error. S<C<"use UNIVERSAL">> without any arguments is still
allowed.

=head1 Deprecations

XXX Any deprecated features, syntax, modules etc. should be listed here.
Expand Down
26 changes: 9 additions & 17 deletions t/op/universal.t
Expand Up @@ -10,7 +10,7 @@ BEGIN {
require "./test.pl";
}

plan tests => 144;
plan tests => 143;

$a = {};
bless $a, "Bob";
Expand Down Expand Up @@ -137,12 +137,10 @@ ok ! (eval { aversion->VERSION(2.719) });
like $@, qr/^Invalid version format/;

my $subs = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::;
## The test for import here is *not* because we want to ensure that UNIVERSAL
## can always import; it is an historical accident that UNIVERSAL can import.
if ('a' lt 'A') {
is $subs, "can import isa DOES VERSION";
is $subs, "can isa DOES VERSION";
} else {
is $subs, "DOES VERSION can import isa";
is $subs, "DOES VERSION can isa";
}

ok $a->isa("UNIVERSAL");
Expand Down Expand Up @@ -177,16 +175,6 @@ ok ! $a->can("export_tags"); # a method in Exporter

ok ! UNIVERSAL::isa("\xff\xff\xff\0", 'HASH');

{
package Pickup;
no warnings "deprecated";
use UNIVERSAL qw( isa can VERSION );

::ok isa "Pickup", UNIVERSAL;
::cmp_ok can( "Pickup", "can" ), '==', \&UNIVERSAL::can;
::ok VERSION "UNIVERSAL" ;
}

{
# test isa() and can() on magic variables
"Human" =~ /(.*)/;
Expand Down Expand Up @@ -274,11 +262,15 @@ use warnings "deprecated";
my $m;
local $SIG{__WARN__} = sub { $m = $_[0] };
eval "use UNIVERSAL 'can'";
like($m, qr/^UNIVERSAL->import is deprecated/,
"deprecation warning for UNIVERSAL->import('can')");
like($@, qr/^UNIVERSAL does not export anything\b/,
"error for UNIVERSAL->import('can')");
is($m, undef,
"no deprecation warning for UNIVERSAL->import('can')");

undef $m;
eval "use UNIVERSAL";
is($@, "",
"no error for UNIVERSAL->import");
is($m, undef,
"no deprecation warning for UNIVERSAL->import");
}
Expand Down
12 changes: 1 addition & 11 deletions t/uni/universal.t
Expand Up @@ -13,7 +13,7 @@ BEGIN {
use utf8;
use open qw( :utf8 :std );

plan tests => 93;
plan tests => 90;

$a = {};
bless $a, "Bòb";
Expand Down Expand Up @@ -117,16 +117,6 @@ cmp_ok UNIVERSAL::can(Àlìcè => "can"), '==', \&UNIVERSAL::can;
eval 'sub UNIVERSAL::slèèp {}';
ok $a->can("slèèp");

{
package Pìckùp;
no warnings "deprecated";
use UNIVERSAL qw( isa can VERSION );

::ok isa "Pìckùp", UNIVERSAL;
::cmp_ok can( "Pìckùp", "can" ), '==', \&UNIVERSAL::can;
::ok VERSION "UNIVERSAL" ;
}

package Fòò;

sub DOES { 1 }
Expand Down

0 comments on commit 1178d2c

Please sign in to comment.