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

$#{@$x} == -1 always, if $x is an array ref #9173

Closed
p5pRT opened this issue Dec 30, 2007 · 14 comments
Closed

$#{@$x} == -1 always, if $x is an array ref #9173

p5pRT opened this issue Dec 30, 2007 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 30, 2007

Migrated from rt.perl.org#49230 (status was 'rejected')

Searchable as RT49230$

@p5pRT
Copy link
Author

p5pRT commented Dec 30, 2007

From @trwyant

This is a bug report for perl from wyant@​cpan.org,
generated with the help of perlbug 1.36 running under perl 5.10.0.


Under Perl 5.10.0, $#{@​$x} appears to return -1 no matter how many
elements are actually in @​$x​:

$ perl5.10.0 -le '$x = [1, 2, 3]; print $#{@​$x}'
-1

$ perl5.8.8 -le '$x = [1, 2, 3]; print $#{@​$x}'
2

I didn't see anything in perldelta to cover this. Yes, the $#
variable is removed, but if Perl 5.10 was parsing $#{...} as
$# followed by {...}, I would think we would get a diagnostic.
And nothing else struck me as being even remotely relevant. Note
that

$ perl5.10.0 -le '@​x = (1, 2, 3); print $#x'
2

and

$ perl5.10.0 -le '$x = [1, 2, 3]; print $#@​$x'
$# is no longer supported at -e line 1.
Array found where operator expected at -e line 1, at end of line
  (Missing operator before ?)
Can't use an undefined value as a symbol reference at -e line 1.



Flags​:
  category=core
  severity=low


Site configuration information for perl 5.10.0​:

Configured by tom at Sat Dec 29 20​:29​:05 EST 2007.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration​:
  Platform​:
  osname=darwin, osvers=7.9.0, archname=darwin-2level
  uname='darwin wyants-white-imac.local 7.9.0 darwin kernel version 7.9.0​: wed mar 30 20​:11​:17 pst 2005; root​:xnuxnu-517.12.7.obj~1release_ppc power macintosh powerpc '
  config_args=''
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=undef, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -pipe -I/usr/local/include',
  optimize='-Os',
  cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='3.3 20030304 (Apple Computer, Inc. build 1671)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib
  libs=-ldbm -ldl -lm -lc
  perllibs=-ldl -lm -lc
  libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dyld.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl 5.10.0​:
  /sw/lib/perl5
  /sw/lib/perl5/darwin
  /usr/local/lib/perl5/5.10.0/darwin-2level
  /usr/local/lib/perl5/5.10.0
  /usr/local/lib/perl5/site_perl/5.10.0/darwin-2level
  /usr/local/lib/perl5/site_perl/5.10.0
  .


Environment for perl 5.10.0​:
  DYLD_LIBRARY_PATH (unset)
  HOME=/Users/tom
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/sw/bin​:/sw/sbin​:/bin​:/sbin​:/usr/local/bin​:/usr/bin​:/usr/sbin​:/Developer/Tools​:/Users/tom/Code/Tools​:/usr/X11R6/bin
  PERL5LIB=/sw/lib/perl5​:/sw/lib/perl5/darwin
  PERLPKGOPT=-noppm
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Dec 30, 2007

From @Abigail

On Sun, Dec 30, 2007 at 09​:55​:17AM -0800, Tom Wyant wrote​:

# New Ticket Created by Tom Wyant
# Please include the string​: [perl #49230]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=49230 >

This is a bug report for perl from wyant@​cpan.org,
generated with the help of perlbug 1.36 running under perl 5.10.0.

-----------------------------------------------------------------
Under Perl 5.10.0, $#{@​$x} appears to return -1 no matter how many
elements are actually in @​$x​:

$ perl5.10.0 -le '$x = [1, 2, 3]; print $#{@​$x}'
-1

$ perl5.8.8 -le '$x = [1, 2, 3]; print $#{@​$x}'
2

I didn't see anything in perldelta to cover this. Yes, the $#
variable is removed, but if Perl 5.10 was parsing $#{...} as
$# followed by {...}, I would think we would get a diagnostic.
And nothing else struck me as being even remotely relevant. Note
that

$ perl5.10.0 -le '@​x = (1, 2, 3); print $#x'
2

and

$ perl5.10.0 -le '$x = [1, 2, 3]; print $#@​$x'
$# is no longer supported at -e line 1.
Array found where operator expected at -e line 1, at end of line
(Missing operator before ?)
Can't use an undefined value as a symbol reference at -e line 1.

Not a bug, but a bug fix. In your case, @​$x equals 3 (as it's in scalar
context). So, it returns $#{"3"}, (which in your case is -1), as the
following code shows​:

  #!/usr/bin/perl

  use 5.010;

  use strict;
  use warnings;
  no warnings 'syntax';

  no strict 'refs';
  @​{"3"} = qw (a b c d e f);

  my $x = [1, 2, 3];
  say $#{@​$x};

  __END__
  5

Which is what I would expect.

Note that 'use strict' would have told you so​:

$ perl -Mstrict -le 'my $x = [1, 2, 3]; print $#{@​$x}'
Can't use string ("3") as an ARRAY ref while "strict refs" in use at -e line 1.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Dec 30, 2007

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

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From blgl@hagernas.com

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

/Bo Lindbergh

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

@rgs - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Dec 31, 2007
@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @demerphq

On 30/12/2007, Bo Lindbergh <blgl@​hagernas.com> wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

There were bugs in older perls where some of this stuff worked fine.
Something similar that still works in 5.10 is​:

  $ ./perl -Ilib -le'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
  bar

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @demerphq

On 31/12/2007, demerphq <demerphq@​gmail.com> wrote​:

On 30/12/2007, Bo Lindbergh <blgl@​hagernas.com> wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

There were bugs in older perls where some of this stuff worked fine.
Something similar that still works in 5.10 is​:

$ ./perl -Ilib -le'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
bar

Although its deprecated​:

  $ ./perl -Ilib -lwe'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
  Using a hash as a reference is deprecated at -e line 1.
  bar

Maybe the change you asked about escaped a deprecation cycle?

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @demerphq

On 31/12/2007, Nicholas Clark <nick@​ccl4.org> wrote​:

On Mon, Dec 31, 2007 at 11​:43​:30AM +0100, demerphq wrote​:

On 31/12/2007, demerphq <demerphq@​gmail.com> wrote​:

On 30/12/2007, Bo Lindbergh <blgl@​hagernas.com> wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

There were bugs in older perls where some of this stuff worked fine.
Something similar that still works in 5.10 is​:

$ ./perl -Ilib -le'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
bar

Although its deprecated​:

$ ./perl -Ilib -lwe'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
Using a hash as a reference is deprecated at -e line 1.
bar

Maybe the change you asked about escaped a deprecation cycle?

We didn't deprecate it. It was a bug which we fixed, rather than a change
from documented behaviour.

This was documented?!

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @nwc10

On Mon, Dec 31, 2007 at 01​:02​:51PM +0100, demerphq wrote​:

On 31/12/2007, Nicholas Clark <nick@​ccl4.org> wrote​:

On Mon, Dec 31, 2007 at 11​:43​:30AM +0100, demerphq wrote​:

On 31/12/2007, demerphq <demerphq@​gmail.com> wrote​:

On 30/12/2007, Bo Lindbergh <blgl@​hagernas.com> wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

There were bugs in older perls where some of this stuff worked fine.
Something similar that still works in 5.10 is​:

$ ./perl -Ilib -le'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
bar

Although its deprecated​:

$ ./perl -Ilib -lwe'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
Using a hash as a reference is deprecated at -e line 1.
bar

Maybe the change you asked about escaped a deprecation cycle?

We didn't deprecate it. It was a bug which we fixed, rather than a change
from documented behaviour.

This was documented?!

No, I meant that the $# syntax was never documented that it worked that way.
as in​: Was a bug. Wasn't documented behaviour.

I intended to be studiously ambiguous on whether using a hash as a reference
was ever documented. But I think that's been seen through now. :-)

The hash as a reference appears to be merely a side effect of the grammar,
and it isn't contradicting any documented behaviour, however unhelpful it
is in practice to be using symbolic array references generated by evaluating
another array in scalar context. Although I'm sure if I asked someone could
obfuscate a JAPH using it.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @nwc10

On Mon, Dec 31, 2007 at 11​:43​:30AM +0100, demerphq wrote​:

On 31/12/2007, demerphq <demerphq@​gmail.com> wrote​:

On 30/12/2007, Bo Lindbergh <blgl@​hagernas.com> wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

There were bugs in older perls where some of this stuff worked fine.
Something similar that still works in 5.10 is​:

$ ./perl -Ilib -le'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
bar

Although its deprecated​:

$ ./perl -Ilib -lwe'use strict; my %hash=(foo=>"bar"); print %hash->{foo};'
Using a hash as a reference is deprecated at -e line 1.
bar

Maybe the change you asked about escaped a deprecation cycle?

We didn't deprecate it. It was a bug which we fixed, rather than a change
from documented behaviour.

We considered the bug fix for 5.8.x for a while, but it turned out that a
couple of important modules had this bug, so it looked likely that it was
widespread enough that it would cause strange runtime pain if people upgraded
from 5.8.8 to 5.8.9 without testing. (Not that we advise that, but inevitably
it will happen, probably as a side effect of Linux package upgrades)

Yes, it will still cause pain when upgrading from 5.8.x to 5.10, but it's
unlikely that anyone will do that in production without first testing.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @druud62

Bo Lindbergh schreef​:

How come this gets reported so often? There's nothing in the current
docs that suggests that $#{@​array} is equivalent to $#array; was
there something in an earlier version?

I guess it comes from trying out constructs to get
the last index of the array of the reference.

Probably $#$aref isn't intuitive?

Arrays of possibly enormous size are copied just to get to it​:

  my @​tmp = @​{$_[0]};
  ... $#tmp ...

in stead of

  $#{$_[0]}
.

(haven't searched google code yet to back my hunch)

--
Affijn, Ruud

"Gewoon is een tijger."

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @trwyant

Another $x = qr{foo}; m/$x/m huh?

I found this in the test suite for a CPAN module. Seeing that the behavior changed between 5.8.8 and 5.10 I filed both places. The module bug is https://rt.cpan.org/Ticket/Display.html?id=32010

Thank you for your prompt response. I'll let the CPAN author know how it came out.

Tom Wyant

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2007

From @trwyant

Message RFC822:
Subject: Re: [perl #49230] $#{@$x} == -1 always, if $x is an array ref
To: harryfmudd@comcast.net
Date: Sun, 30 Dec 2007 20:56:11 +0000
From: "Abigail via RT" perlbug-followup@perl.org
Content-Type: application/pgp-signature
Content-Disposition: inline
Content-Transfer-Encoding: base64
Content-Length: 189

LS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0KVmVyc2lvbjogR251UEcg
djEuNC4wIChHTlUvTGludXgpCgppRDhEQlFGSGQvemplMWNVQWVYa2dva1JB
bVdWQUo5SkZhNFlKL3FrZ3hvVW93Wm9QVU5CUDZSN1d3Q2Zhem9yClZVWHpv
WTBNUUVSZjk1cVU0bVNFUzBBPQo9eStMagotLS0tLUVORCBQR1AgU0lHTkFU
VVJFLS0tLS0K

@p5pRT
Copy link
Author

p5pRT commented Jan 2, 2008

From @schwern

Bo Lindbergh wrote​:

How come this gets reported so often? There's nothing in the current docs
that suggests that $#{@​array} is equivalent to $#array; was there something
in an earlier version?

Because try something and it happens to work. And since they don't turn on
warnings they have no reason to believe it's not a feature.

--
Stabbing you in the face so you don't have to.

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

1 participant