Skip Menu |

This queue is for tickets about the PDF-API2 CPAN distribution.

Report information
The Basics
Id: 42622
Status: rejected
Priority: 0/
Queue: PDF-API2

People
Owner: Nobody in particular
Requestors: dfs [...] roaringpenguin.com
dfs+pause [...] roaringpenguin.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Hello, In one of my unit tests for a product we're developing, I get many errors like this: Called UNIVERSAL::can() as a function, not a method at /usr/share/perl5/PDF/API2/Basic/PDF/Objind.pm line 150 According to 'perldoc UNIVERSAL::can': Some authors call methods in the UNIVERSAL class on potential invocants as functions, bypassing any possible overriding. This is wrong and you should not do it. Unfortunately, not everyone heeds this warning and their bad code can break your good code. I'm wondering if you can go through and fix all instances of: UNIVERSAL::can($object, 'method') to be: $object->can('method') Thanks, David.
Subject: Many "Called UNIVERSAL::can() as a function" warnings
Hi, I opened a ticket about this earlier, but I forgot to set the Subject. :-( Please see http://rt.cpan.org/Public/Bug/Display.html?id=41766 Regards, David.
The attached patch converts UNIVERSAL::can($foo, 'method') to the more-correct (or, at least, less nagging) blessed($foo) && $foo->can('method') This requires Scalar::Util to obtain 'blessed'. This shouldn't be a dependency problem as PDF::API2 relies on other perl 5.8 features.
diff --git a/lib/PDF/API2/Basic/PDF/Array.pm b/lib/PDF/API2/Basic/PDF/Array.pm index f59f64a..87fb758 100644 --- a/lib/PDF/API2/Basic/PDF/Array.pm +++ b/lib/PDF/API2/Basic/PDF/Array.pm @@ -32,6 +32,8 @@ use vars qw(@ISA); use PDF::API2::Basic::PDF::Objind; @ISA = qw(PDF::API2::Basic::PDF::Objind); +use Scalar::Util qw(blessed); + no warnings qw[ deprecated recursion uninitialized ]; =head1 NAME @@ -172,7 +174,7 @@ sub copy $res->{' val'} = []; foreach $e (@{$self->{' val'}}) { - if (UNIVERSAL::can($e, "is_obj") && !$e->is_obj($pdf)) + if (blessed($e) && $e->can('is_obj') && !$e->is_obj($pdf)) { push(@{$res->{' val'}}, $e->copy($pdf)); } else { push(@{$res->{' val'}}, $e); } diff --git a/lib/PDF/API2/Basic/PDF/File.pm b/lib/PDF/API2/Basic/PDF/File.pm index a937106..1763cca 100644 --- a/lib/PDF/API2/Basic/PDF/File.pm +++ b/lib/PDF/API2/Basic/PDF/File.pm @@ -198,6 +198,7 @@ use PDF::API2::Basic::PDF::String; use PDF::API2::Basic::PDF::Page; use PDF::API2::Basic::PDF::Pages; use PDF::API2::Basic::PDF::Null; +use Scalar::Util qw(blessed); no warnings qw[ deprecated recursion uninitialized ]; @@ -358,7 +359,7 @@ sub release map { $self->{$_}=undef; delete $self->{$_}; } keys %{$self}; while (my $item = shift @tofree) { - if (UNIVERSAL::can($item,'release')) + if (blessed($item) && $item->can('release')) { $item->release(1); } diff --git a/lib/PDF/API2/Basic/PDF/Filter.pm b/lib/PDF/API2/Basic/PDF/Filter.pm index b418111..7ef4d36 100644 --- a/lib/PDF/API2/Basic/PDF/Filter.pm +++ b/lib/PDF/API2/Basic/PDF/Filter.pm @@ -28,6 +28,8 @@ package PDF::API2::Basic::PDF::Filter; no warnings qw[ deprecated recursion uninitialized ]; +use Scalar::Util qw(blessed); + =head1 NAME PDF::API2::Basic::PDF::Filter - Abstract superclass for PDF stream filters @@ -98,7 +100,7 @@ sub release while (my $item = shift @tofree) { my $ref = ref($item); - if (UNIVERSAL::can($item, 'release')) + if (blessed($item) && $item->can('release')) { $item->release(); } elsif ($ref eq 'ARRAY') { push( @tofree, @{$item} ); } diff --git a/lib/PDF/API2/Basic/PDF/Literal.pm b/lib/PDF/API2/Basic/PDF/Literal.pm index eeeae32..f5916bd 100644 --- a/lib/PDF/API2/Basic/PDF/Literal.pm +++ b/lib/PDF/API2/Basic/PDF/Literal.pm @@ -42,6 +42,7 @@ use PDF::API2::Basic::PDF::Objind; use PDF::API2::Basic::PDF::Filter; use PDF::API2::Basic::PDF::Name; +use Scalar::Util qw(blessed); no warnings qw[ deprecated recursion uninitialized ]; @@ -91,7 +92,7 @@ sub outobjdeep { $fh->print('<<'.join(' ', map { '/'.PDF::API2::Basic::PDF::Name::string_to_name($_).' '.$self->{$k}->{$_} } sort keys %{$self->{$k}})." >>\n"); } - elsif(UNIVERSAL::can($self->{$k},'outobj')) + elsif(blessed($self->{$k}) && $self->{$k}->can('outobj')) { $self->{$k}->outobj($fh, $pdf, %opts); $fh->print("\n"); diff --git a/lib/PDF/API2/Basic/PDF/Objind.pm b/lib/PDF/API2/Basic/PDF/Objind.pm index f8df2e6..2d4105c 100644 --- a/lib/PDF/API2/Basic/PDF/Objind.pm +++ b/lib/PDF/API2/Basic/PDF/Objind.pm @@ -72,6 +72,7 @@ Holds a direct reference to the next free object in the free list. use strict; use vars qw(@inst %inst $uidc); no warnings qw[ deprecated recursion uninitialized ]; +use Scalar::Util qw(blessed); # protected keys during emptying and copying, etc. @@ -147,7 +148,7 @@ sub __release while (my $item = shift @tofree) { my $ref = ref($item); - if (UNIVERSAL::can($item, 'release')) + if (blessed($item) && $item->can('release')) { $item->release($force); } elsif ($ref eq 'ARRAY') { push( @tofree, @{$item} ); } @@ -174,7 +175,7 @@ sub release while(my $item = shift @tofree) { my $ref = ref($item) || next; # common case: value is not reference - if(UNIVERSAL::can($item, 'release')) + if(blessed($item) && $item->can('release')) { $item->release(); } @@ -365,7 +366,7 @@ sub copy { next if $inst{$k}; next if defined $res->{$k}; - if (UNIVERSAL::can($self->{$k}, "is_obj") && !$self->{$k}->is_obj($pdf)) + if (blessed($self->{$k}) && $self->{$k}->can('is_obj') && !$self->{$k}->is_obj($pdf)) { $res->{$k} = $self->{$k}->copy($pdf); } else { $res->{$k} = $self->{$k}; } diff --git a/lib/PDF/API2/Basic/TTF/Font.pm b/lib/PDF/API2/Basic/TTF/Font.pm index 313fa3c..00b6fd9 100644 --- a/lib/PDF/API2/Basic/TTF/Font.pm +++ b/lib/PDF/API2/Basic/TTF/Font.pm @@ -141,6 +141,7 @@ use IO::File; use strict; use vars qw(%tables $VERSION $dumper); use Symbol(); +use Scalar::Util qw(blessed); require 5.006; @@ -694,7 +695,7 @@ sub release while (my $item = shift @tofree) { my $ref = ref($item); - if (UNIVERSAL::can($item, 'release')) + if (blessed($item) && $item->can('release')) { $item->release(); } elsif ($ref eq 'ARRAY') { push( @tofree, @{$item} ); } diff --git a/lib/PDF/API2/Basic/TTF/Table.pm b/lib/PDF/API2/Basic/TTF/Table.pm index 152985b..164efbf 100644 --- a/lib/PDF/API2/Basic/TTF/Table.pm +++ b/lib/PDF/API2/Basic/TTF/Table.pm @@ -373,7 +373,7 @@ sub release while (my $item = shift @tofree) { my $ref = ref($item); - if (UNIVERSAL::can($item, 'release')) + if (blessed($item) && $item->can('release')) { $item->release(); } elsif ($ref eq 'ARRAY') { push( @tofree, @{$item} ); } diff --git a/lib/PDF/API2/Lite.pm b/lib/PDF/API2/Lite.pm index d31c50b..e425ba8 100644 --- a/lib/PDF/API2/Lite.pm +++ b/lib/PDF/API2/Lite.pm @@ -38,6 +38,7 @@ BEGIN { use PDF::API2; use PDF::API2::Util; use PDF::API2::Basic::PDF::Utils; + use Scalar::Util qw(blessed); use POSIX qw( ceil floor ); @@ -134,9 +135,9 @@ sub saveas { } $self->{api}->end; foreach my $k (keys %{$self}) { - if(UNIVERSAL::can($k,'release')) { + if(blessed($k) && $k->can('release')) { $k->release(1); - } elsif(UNIVERSAL::can($k,'end')) { + } elsif(blessed($k) && $k->can('end')) { $k->end; } $self->{$k}=undef; diff --git a/lib/PDF/API2/Resource/BaseFont.pm b/lib/PDF/API2/Resource/BaseFont.pm index 7c8aee2..ccd8feb 100644 --- a/lib/PDF/API2/Resource/BaseFont.pm +++ b/lib/PDF/API2/Resource/BaseFont.pm @@ -41,7 +41,8 @@ BEGIN { use PDF::API2::Basic::PDF::Utils; use PDF::API2::Resource; use Compress::Zlib; - + use Scalar::Util qw(blessed); + use vars qw(@ISA $VERSION); @ISA = qw( PDF::API2::Resource ); @@ -150,7 +151,7 @@ sub tounicodemap { $cmap.=qq| /Supplement 0\n|; $cmap.=qq|>> def\n|; $cmap.=sprintf(qq|/CMapName /pdfapi2-%s+0 def\n|,$self->name); - if(UNIVERSAL::can($self,'uniByCId') && UNIVERSAL::can($self,'glyphNum')) { + if(blessed($self) && $self->can('uniByCId') && blessed($self) && $self->can('glyphNum')) { # this is a type0 font $cmap.=sprintf(qq|1 begincodespacerange <0000> <%04X> endcodespacerange\n|,$self->glyphNum-1); for(my $j=0;$j<$self->glyphNum;$j++) { diff --git a/lib/PDF/API2/Resource/CIDFont.pm b/lib/PDF/API2/Resource/CIDFont.pm index 0ac2032..576b17d 100644 --- a/lib/PDF/API2/Resource/CIDFont.pm +++ b/lib/PDF/API2/Resource/CIDFont.pm @@ -41,6 +41,7 @@ BEGIN use PDF::API2::Util; use PDF::API2::Basic::PDF::Utils; use PDF::API2::Resource::BaseFont; + use Scalar::Util qw(blessed); use POSIX; @@ -195,7 +196,7 @@ sub cidsByStr { $text=$self->cidsByUtf(decode($self->data->{encode},$text)); } - elsif(!is_utf8($text) && UNIVERSAL::can($self,'issymbol') && $self->issymbol && $self->data->{decode} eq 'ident') + elsif(!is_utf8($text) && blessed($self) && $self->can('issymbol') && $self->issymbol && $self->data->{decode} eq 'ident') { $text=pack('U*',(map { $_+0xf000 } unpack('C*',$text))); $text=$self->cidsByUtf($text); @@ -261,7 +262,7 @@ sub text sub text_cid { my ($self,$text,$size)=@_; - if(UNIVERSAL::can($self,'fontfile')) + if(blessed($self) && $self->can('fontfile')) { foreach my $g (unpack('n*',$text)) { @@ -282,7 +283,7 @@ sub text_cid sub text_cid_kern { my ($self,$text,$size,$ident)=@_; - if(UNIVERSAL::can($self,'fontfile')) + if(blessed($self) && $self->can('fontfile')) { foreach my $g (unpack('n*',$text)) { diff --git a/lib/PDF/API2/Resource/XObject/Image/GD.pm b/lib/PDF/API2/Resource/XObject/Image/GD.pm index e1ae004..2fba4ee 100644 --- a/lib/PDF/API2/Resource/XObject/Image/GD.pm +++ b/lib/PDF/API2/Resource/XObject/Image/GD.pm @@ -39,6 +39,7 @@ BEGIN { use PDF::API2::Resource::XObject::Image; use POSIX; + use Scalar::Util qw(blessed); use vars qw(@ISA $VERSION); @@ -101,13 +102,13 @@ sub read_gd { $self->bpc(8); $self->colorspace('DeviceRGB'); - if(UNIVERSAL::can($gd,'jpeg') && ($c > 256) && !$opts{-lossless}) { + if(blessed($gd) && $gd->can('jpeg') && ($c > 256) && !$opts{-lossless}) { $self->filters('DCTDecode'); $self->{' nofilt'}=1; $self->{' stream'}=$gd->jpeg(75); - } elsif(UNIVERSAL::can($gd,'raw')) { + } elsif(blessed($gd) && $gd->can('raw')) { $self->filters('FlateDecode'); $self->{' stream'}=$gd->raw; @@ -184,4 +185,4 @@ alfred reibenschuh added CVS id/log -=cut \ No newline at end of file +=cut
This warning is the result of using a module that changes core Perl behavior. To get rid of the warning, look for and eliminate a "use UNIVERSAL::can" line elsewhere in your code.