Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

UNIVERSAL::can reports that undef is an object? #1148

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#2110 (status was 'resolved')

Searchable as RT2110$

p5pRT commented 24 years ago

From sburke@stonehenge.netadventure.net

Each of these   $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F';   $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F';   $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F'; do print 'F'\, as expected.

But this   $x = undef; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; prints 'T'.

UNIVERSAL​::isa ( VAL\, TYPE ) isa returns true if the first argument is a reference and either of the following statements is true.

  VAL is a blessed reference and is blessed into package TYPE or   inherits from package TYPE

  VAL is a reference to a TYPE of perl variable (er 'HASH')

I take the "if" to mean "if and only if"\, so UNIVERSAL​::isa(undef\, anything) should return false.

Also\, I suggest s/er/e.g./\, and s/perl/Perl/ in the text there.

-- Sean M. Burke sburke@​netadventure.net http​://www.netadventure.net/~sburke/

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Whoops\, I forgot to note my version of Perl. It's​:

% perl -V Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:   Platform​:   osname=aix\, osvers=4.3.1.0\, archname=aix   uname='aix pegasus 3 4 000165185700 '   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=undef useperlio=undef d_sfio=undef   Compiler​:   cc='cc'\, optimize='-O'\, gccversion=   cppflags='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=8192 -I/usr/local/include -I/usr/local/gnu/include'   ccflags ='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE -qmaxmem=8192 -I/usr/local/include -I/usr/local/gnu/include'   stdchar='unsigned char'\, d_stdstdio=define\, usevfork=false   intsize=4\, longsize=4\, ptrsize=4\, doublesize=8   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=8   alignbytes=8\, usemymalloc=n\, prototype=define   Linker and Libraries​:   ld='ld'\, ldflags ='-L/usr/local/lib -L/usr/local/gnu/lib -L/usr/ccs/lib -L/lib'   libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib /usr/local/gnu/lib   libs=-lnsl -lgdbm -ldbm -ldl -lld -lm -lc -lcrypt -lbsd -lPW   libc=\, so=a\, useshrplib=false\, libperl=libperl.a   Dynamic Linking​:   dlsrc=dl_aix.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-bE​:perl.exp'   cccdlflags=' '\, lddlflags='-bhalt​:4 -bM​:SRE -bI​:$(PERL_INC)/perl.exp -bE​:$(BASEEXT).exp -b noentry -lc -L/usr/local/lib -L/usr/local/gnu/lib -L/usr/ccs/lib -L/lib'

Characteristics of this binary (from libperl)​:   Built under aix   Compiled at Aug 12 1999 09​:10​:29   %ENV​:   PERLLIB="/nfs/user/l/lachler/.bin/perl"   @​INC​:   /nfs/user/l/lachler/.bin/perl   /usr/local/gnu/lib/perl5/5.00503/aix   /usr/local/gnu/lib/perl5/5.00503   /usr/local/gnu/lib/perl5/site_perl/5.005/aix   /usr/local/gnu/lib/perl5/site_perl/5.005   .

-- Sean M. Burke sburke@​netadventure.net http​://www.netadventure.net/~sburke/

p5pRT commented 24 years ago

From @ysth

In article \200002070122\.RAA22777@​stonehenge\.netadventure\.net\, "Sean M. Burke" \sburke@​stonehenge\.netadventure\.net wrote​:

Each of these $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F'; do print 'F'\, as expected.

But this $x = undef; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; prints 'T'.

Not a bug. The undef is treated as '' (with the usual warning\, for folks that believe in warnings)\, and '' is another name for 'main'. 'main' indeed isa 'UNIVERSAL'.

Also note this​: { package fish; package Stuff } # Make some packages ${"123​::foo"} = 1; # Create an 'illegal' package name @​​::ISA = 'Stuff'; # Note the package name $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F';

Now they all print 'T'\, as expected.

UNIVERSAL​::isa ( VAL\, TYPE ) isa returns true if the first argument is a reference and either of the following statements is true.

VAL is a blessed reference and is blessed into package TYPE or inherits from package TYPE

VAL is a reference to a TYPE of perl variable (er 'HASH')

I take the "if" to mean "if and only if"\, so UNIVERSAL​::isa(undef\, anything) should return false.

Also\, I suggest s/er/e.g./\, and s/perl/Perl/ in the text there.

Here's a patch​:

Inline Patch ```diff --- UNIVERSAL.pm-pre Wed Jan 26 21:38:52 2000 +++ UNIVERSAL.pm Mon Feb 7 09:25:50 2000 @@ -62,19 +62,23 @@ =item UNIVERSAL::isa ( VAL, TYPE ) -C returns I if the first argument is a reference and either -of the following statements is true. +C returns I if one of the following statements is true. =over 8 =item * -C is a blessed reference and is blessed into package C -or inherits from package C +C is a reference blessed into either package C or a package +which inherits from package C. =item * -C is a reference to a C of perl variable (er 'HASH') +C is a reference to a C of Perl variable (e.g. 'HASH'). + +=item * + +C is the name of a package that inherits from (or is itself) +package C. =back ```
p5pRT commented 24 years ago

From @gbarr

No\, isa and can should do the same as a normal method call and both of the following fail

$ perl -e '$p->VERSION' Can't call method "VERSION" on an undefined value at -e line 1. $ perl -e '$p=""; $p->VERSION' Can't call method "VERSION" without a package or object reference at -e line 1.

So isa and can should to the same. Here is a patch

Inline Patch ```diff --- universal.c.orig Tue Feb 8 15:12:42 2000 +++ universal.c Tue Feb 8 15:23:55 2000 @@ -140,6 +140,10 @@ Perl_croak(aTHX_ "Usage: UNIVERSAL::isa(reference, kind)"); sv = ST(0); + + if (!SvOK(sv) || !SvCUR(sv)) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1),n_a); ST(0) = boolSV(sv_derived_from(sv, name)); @@ -159,6 +163,10 @@ Perl_croak(aTHX_ "Usage: UNIVERSAL::can(object-ref, method)"); sv = ST(0); + + if (!SvOK(sv) || !SvCUR(sv)) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1),n_a); rv = &PL_sv_undef; ```

On Mon, Feb 07, 2000 at 10:51:43AM -0800, Yitzchak Scott-Thoennes wrote:

In article \200002070122\.RAA22777@​stonehenge\.netadventure\.net\, "Sean M. Burke" \sburke@​stonehenge\.netadventure\.net wrote​:

Each of these $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F'; do print 'F'\, as expected.

But this $x = undef; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; prints 'T'.

Not a bug. The undef is treated as '' (with the usual warning\, for folks that believe in warnings)\, and '' is another name for 'main'. 'main' indeed isa 'UNIVERSAL'.

Also note this​: { package fish; package Stuff } # Make some packages ${"123​::foo"} = 1; # Create an 'illegal' package name @​​::ISA = 'Stuff'; # Note the package name $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F';

Now they all print 'T'\, as expected.

UNIVERSAL​::isa ( VAL\, TYPE ) isa returns true if the first argument is a reference and either of the following statements is true.

VAL is a blessed reference and is blessed into package TYPE or inherits from package TYPE

VAL is a reference to a TYPE of perl variable (er 'HASH')

I take the "if" to mean "if and only if"\, so UNIVERSAL​::isa(undef\, anything) should return false.

Also\, I suggest s/er/e.g./\, and s/perl/Perl/ in the text there.

Here's a patch​:

--- UNIVERSAL.pm-pre Wed Jan 26 21​:38​:52 2000 +++ UNIVERSAL.pm Mon Feb 7 09​:25​:50 2000 @​@​ -62\,19 +62\,23 @​@​

=item UNIVERSAL​::isa ( VAL\, TYPE )

-C\ returns I\ if the first argument is a reference and either -of the following statements is true. +C\ returns I\ if one of the following statements is true.

=over 8

=item *

-C\ is a blessed reference and is blessed into package C\ -or inherits from package C\ +C\ is a reference blessed into either package C\ or a package +which inherits from package C\.

=item *

-C\ is a reference to a C\ of perl variable (er 'HASH') +C\ is a reference to a C\ of Perl variable (e.g. 'HASH'). + +=item * + +C\ is the name of a package that inherits from (or is itself) +package C\.

=back

p5pRT commented 24 years ago

From @gbarr

Whoops\, posted before testing. This patch is right.

Graham.

Inline Patch ```diff --- universal.c.orig Tue Feb 8 15:12:42 2000 +++ universal.c Tue Feb 8 15:41:09 2000 @@ -140,6 +140,10 @@ Perl_croak(aTHX_ "Usage: UNIVERSAL::isa(reference, kind)"); sv = ST(0); + + if (!SvOK(sv) || !(SvROK(sv) || SvCUR(sv))) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1),n_a); ST(0) = boolSV(sv_derived_from(sv, name)); @@ -159,6 +163,10 @@ Perl_croak(aTHX_ "Usage: UNIVERSAL::can(object-ref, method)"); sv = ST(0); + + if (!SvOK(sv) || !(SvROK(sv) || SvCUR(sv))) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1),n_a); rv = &PL_sv_undef; ```

On Tue, Feb 08, 2000 at 03:25:14PM +0000, Graham Barr wrote:

No\, isa and can should do the same as a normal method call and both of the following fail

$ perl -e '$p->VERSION' Can't call method "VERSION" on an undefined value at -e line 1. $ perl -e '$p=""; $p->VERSION' Can't call method "VERSION" without a package or object reference at -e line 1.

So isa and can should to the same. Here is a patch

--- universal.c.orig Tue Feb 8 15​:12​:42 2000 +++ universal.c Tue Feb 8 15​:23​:55 2000 @​@​ -140\,6 +140\,10 @​@​ Perl_croak(aTHX_ "Usage​: UNIVERSAL​::isa(reference\, kind)");

 sv = ST\(0\);

+ + if (!SvOK(sv) || !SvCUR(sv)) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1)\,n_a);

 ST\(0\) = boolSV\(sv\_derived\_from\(sv\, name\)\);

@​@​ -159\,6 +163\,10 @​@​ Perl_croak(aTHX_ "Usage​: UNIVERSAL​::can(object-ref\, method)");

 sv = ST\(0\);

+ + if (!SvOK(sv) || !SvCUR(sv)) + XSRETURN_UNDEF; + name = (char *)SvPV(ST(1)\,n_a); rv = &PL_sv_undef;

On Mon\, Feb 07\, 2000 at 10​:51​:43AM -0800\, Yitzchak Scott-Thoennes wrote​:

In article \200002070122\.RAA22777@​stonehenge\.netadventure\.net\, "Sean M. Burke" \sburke@​stonehenge\.netadventure\.net wrote​:

Each of these $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F'; do print 'F'\, as expected.

But this $x = undef; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; prints 'T'.

Not a bug. The undef is treated as '' (with the usual warning\, for folks that believe in warnings)\, and '' is another name for 'main'. 'main' indeed isa 'UNIVERSAL'.

Also note this​: { package fish; package Stuff } # Make some packages ${"123​::foo"} = 1; # Create an 'illegal' package name @​​::ISA = 'Stuff'; # Note the package name $x = 123; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = 'fish'; print UNIVERSAL​::isa($x\, "UNIVERSAL") ? 'T' : 'F'; $x = undef; print UNIVERSAL​::isa($x\, "Stuff" ) ? 'T' : 'F';

Now they all print 'T'\, as expected.

UNIVERSAL​::isa ( VAL\, TYPE ) isa returns true if the first argument is a reference and either of the following statements is true.

VAL is a blessed reference and is blessed into package TYPE or inherits from package TYPE

VAL is a reference to a TYPE of perl variable (er 'HASH')

I take the "if" to mean "if and only if"\, so UNIVERSAL​::isa(undef\, anything) should return false.

Also\, I suggest s/er/e.g./\, and s/perl/Perl/ in the text there.

Here's a patch​:

--- UNIVERSAL.pm-pre Wed Jan 26 21​:38​:52 2000 +++ UNIVERSAL.pm Mon Feb 7 09​:25​:50 2000 @​@​ -62\,19 +62\,23 @​@​

=item UNIVERSAL​::isa ( VAL\, TYPE )

-C\ returns I\ if the first argument is a reference and either -of the following statements is true. +C\ returns I\ if one of the following statements is true.

=over 8

=item *

-C\ is a blessed reference and is blessed into package C\ -or inherits from package C\ +C\ is a reference blessed into either package C\ or a package +which inherits from package C\.

=item *

-C\ is a reference to a C\ of perl variable (er 'HASH') +C\ is a reference to a C\ of Perl variable (e.g. 'HASH'). + +=item * + +C\ is the name of a package that inherits from (or is itself) +package C\.

=back