Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

u$a and $b not set properly when calling a sort comparator in another package #14028

Open
p5pRT opened this issue Aug 15, 2014 · 6 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Aug 15, 2014

Migrated from rt.perl.org#122545 (status was 'open')

Searchable as RT122545$

@p5pRT
Copy link
Author

p5pRT commented Aug 15, 2014

From @mjdominus

Created by @mjdominus

  package A;

  sub scmp { print "$a $b\n"; return $a <=> $b }

  package B;

  @​b = sort A​::scmp reverse(1..4);
  print "@​b\n";

The $a and $b values are not properly passed to A​::scmp. Instead the
values to be compared are placed into $B​::a and $B​::b. But they need
to be in $A​::a and $A​::b so that A​::scmp can access them. Because
they aren't, A​::scmp prints nothing, emits many "Use of uninitialized
value" warnings, and returns the wrong results.

The sort operator could handle this properly, because it knows (or
could know) that the comparator is in package A, so the data should be
placed in the $a and $b variables for that package. But with the way
sort works now, it is impossible to write A​::scmp to work correctly,
because it can't know which package variables into which sort will
place the data.

Moreover, this deficiency isn't documented, although it seems to be hinted at by the

  sub backwards ($$) { $_[1] cmp $_[0]; }

example.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.14.2:

Configured by Debian Project at Tue Feb  4 23:09:53 UTC 2014.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
   
  Platform:
    osname=linux, osvers=2.6.42-37-generic, archname=x86_64-linux-gnu-thread-multi
    uname='linux panlong 2.6.42-37-generic #58-ubuntu smp thu jan 24 15:28:10 utc 2013 x86_64 x86_64 x86_64 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14 -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2 -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.14.2 -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.6.3', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2
    gnulibc_version='2.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib -fstack-protector'

Locally applied patches:
    


@INC for perl 5.14.2:
    /etc/perl
    /usr/local/lib/perl/5.14.2
    /usr/local/share/perl/5.14.2
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.14
    /usr/share/perl/5.14
    /usr/local/lib/site_perl
    .


Environment for perl 5.14.2:
    HOME=/home/mjd
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/mjd/bin:/usr/local/nmh/bin:/home/mjd/misc/blog/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/var/qmail/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2014

From @iabyn

On Fri, Aug 15, 2014 at 04​:35​:15PM -0700, Mark-Jason Dominus wrote​:

package A; 

sub scmp \{ print "$a $b\\n"; return $a \<=> $b \}

package B;

@&#8203;b = sort A&#8203;::scmp reverse\(1\.\.4\);
print "@&#8203;b\\n";

The $a and $b values are not properly passed to A​::scmp. Instead the
values to be compared are placed into $B​::a and $B​::b. But they need
to be in $A​::a and $A​::b so that A​::scmp can access them. Because
they aren't, A​::scmp prints nothing, emits many "Use of uninitialized
value" warnings, and returns the wrong results.

The sort operator could handle this properly, because it knows (or
could know) that the comparator is in package A, so the data should be
placed in the $a and $b variables for that package. But with the way
sort works now, it is impossible to write A​::scmp to work correctly,
because it can't know which package variables into which sort will
place the data.

I think that might open a can of inconsistent worms. For example,
which package should $a and $b be chosen from in the following​:

  package A;
  *B​::scmp = sub {...};
  package C;
  @​b = sort B​::scmp reverse(1..4);

or potentially

  package A;
  *B​::f = sub { $a <=> $b+1};
  package C;
  delete $​::{'A​::'};
  @​b = sort B​::scmp reverse(1..4);

--
No man treats a motor car as foolishly as he treats another human being.
When the car will not go, he does not attribute its annoying behaviour to
sin, he does not say, You are a wicked motorcar, and I shall not give you
any more petrol until you go. He attempts to find out what is wrong and
set it right.
  -- Bertrand Russell,
  Has Religion Made Useful Contributions to Civilization?

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2014

From @ikegami

On Mon, Aug 18, 2014 at 6​:27 AM, Dave Mitchell <davem@​iabyn.com> wrote​:

I think that might open a can of inconsistent worms. For example,
which package should $a and $b be chosen from in the following​:

package A;
\*B&#8203;::scmp = sub \{\.\.\.\};
package C;
@&#8203;b = sort B&#8203;::scmp reverse\(1\.\.4\);

or potentially

package A;
\*B&#8203;::f = sub \{ $a \<=> $b\+1\};
package C;
delete $&#8203;::\{'A&#8203;::'\};
@&#8203;b = sort B&#8203;::scmp reverse\(1\.\.4\);

Easy​: A, as scmp reads $A​::a and $A​::b.

This information is readily available.

$ perl -MDevel​::Peek -e'package A; *B​::scmp = sub {...}; package C;
Devel​::Peek​::Dump(\&B​::scmp);'
SV = IV(0x2406f58) at 0x2406f68
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x2425a28
  SV = PVCV(0x24240e8) at 0x2425a28
  REFCNT = 3
  FLAGS = (PADMY,ANON,WEAKOUTSIDE,CVGV_RC,DYNFILE)
  COMP_STASH = 0x242f910 "A"
  START = 0x240c308 ===> 1
  ROOT = 0x240c250
  GVGV​::GV = 0x2462058 "A" :​: "__ANON__"
  FILE = "-e"
  DEPTH = 0
  FLAGS = 0x1490
  OUTSIDE_SEQ = 93
  PADLIST = 0x242f630
  PADNAME = 0x242f928(0x2434470) PAD = 0x242fdf0(0x24318e0)
  OUTSIDE = 0x2407148 (MAIN)

@p5pRT
Copy link
Author

p5pRT commented Aug 18, 2014

From @iabyn

On Mon, Aug 18, 2014 at 06​:30​:36PM -0400, Eric Brine wrote​:

On Mon, Aug 18, 2014 at 6​:27 AM, Dave Mitchell <davem@​iabyn.com> wrote​:

I think that might open a can of inconsistent worms. For example,
which package should $a and $b be chosen from in the following​:

package A;
\*B&#8203;::scmp = sub \{\.\.\.\};
package C;
@&#8203;b = sort B&#8203;::scmp reverse\(1\.\.4\);

or potentially

package A;
\*B&#8203;::f = sub \{ $a \<=> $b\+1\};
package C;
delete $&#8203;::\{'A&#8203;::'\};
@&#8203;b = sort B&#8203;::scmp reverse\(1\.\.4\);

Easy​: A, as scmp reads $A​::a and $A​::b.

This information is readily available.

Except that it isn't for the second example I gave​:

$ p -MDevel​::Peek -e'package A; *B​::scmp = sub {...}; package C; delete $​::{"A​::"}; Devel​::Peek​::Dump(\&B​::scmp);'
SV = IV(0x1234048) at 0x1234058
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x12340a0
  SV = PVCV(0x1227f10) at 0x12340a0
  REFCNT = 3
  FLAGS = (PADMY,ANON,WEAKOUTSIDE,CVGV_RC,DYNFILE)
  COMP_STASH = 0x0
  START = 0x12388f8 ===> 1
  ROOT = 0x1238840
  GVGV​::GV = 0x1234160 __ANON__"
  FILE = "-e"
  DEPTH = 0
  FLAGS = 0x1490
  OUTSIDE_SEQ = 43
  PADLIST = 0x12382a8
  PADNAME = 0x126a928(0x1238c38) PAD = 0x1234520(0x1221ba8)
  OUTSIDE = 0x12090f0 (MAIN)

which is what I meant about a can of inconsistent worms; i.e. it will
*mostly* choose package A, except when it doesn't.

--
The crew of the Enterprise encounter an alien life form which is
surprisingly neither humanoid nor made from pure energy.
  -- Things That Never Happen in "Star Trek" #22

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2014

From @ikegami

On Mon, Aug 18, 2014 at 7​:42 PM, Dave Mitchell <davem@​iabyn.com> wrote​:

Except that it isn't for the second example I gave​:

oops, I must have botched my test.

which is what I meant about a can of inconsistent worms; i.e. it will

*mostly* choose package A, except when it doesn't.

How often do people delete packages? It's rather common to delete from
packages, but entire packages? Specifically, is it too common to issue a
warning in that situation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants