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

Spurious 'Modification of a read-only value' #808

Closed
p5pRT opened this issue Nov 3, 1999 · 14 comments
Closed

Spurious 'Modification of a read-only value' #808

p5pRT opened this issue Nov 3, 1999 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 3, 1999

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

Searchable as RT1735$

@p5pRT
Copy link
Author

p5pRT commented Nov 3, 1999

From mjtg@cus.cam.ac.uk

gives the errors

  Useless use of defined operator in void context at -e line 1.
  Modification of a read-only value attempted at -e line 1.

Simpler examples give the expected warnings

  perl -we '${$1}'
  Useless use of a variable in void context at -e line 1.
  Use of uninitialized value at -e line 1.

  perl -we 'defined ${+undef}'
  Useless use of defined operator in void context at -e line 1.
  Use of uninitialized value at -e line 1.

This didn't happen in perl5.003 FWIW. Something to do with
autovivication of references to scalars?

Mike Guy

% perl5.005_62a -V
Summary of my perl5 (revision 5.0 version 5 subversion 62) configuration​:
  Platform​:
  osname=sunos, osvers=4.1.3, archname=sun4-sunos
  uname='sunos nmg1.csi. 4.1.3 1 sun4c '
  config_args='-Doptimise=-O -Uusethreads -des'
  hint=previous, useposix=true, d_sigaction=define
  usethreads=undef useperlio=undef d_sfio=undef
  use64bits=undef usemultiplicity=undef
  Compiler​:
  cc='gcc', optimize='-O', gccversion=2.7.2.3
  cppflags='-I/usr/local/include'
  ccflags ='-I/usr/local/include'
  stdchar='unsigned char', d_stdstdio=define, usevfork=true
  intsize=4, longsize=4, ptrsize=4, doublesize=8
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
  alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries​:
  ld='ld', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/ucblib
  libs=-ldbm -ldl -lm -lc -lposix
  libc=/lib/libc.so.1.8, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
  cccdlflags='-fpic', lddlflags='-assert nodefinitions -L/usr/local/lib'

Characteristics of this binary (from libperl)​:
  Locally applied patches​:
  perldoc.temp
  install.w
  Built under sunos
  Compiled at Oct 27 1999 01​:31​:39
  @​INC​:
  /home/mjtg/perl5.005_62a/lib
  /home/mjtg/perl5.005_62a/lib
  /home/mjtg/perl5.005_62a/lib/site_perl
  .

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2000

From [Unknown Contact. See original ticket]

Still in 8101....

  perl -we 'defined ${$1}'

gives the errors

  Useless use of defined operator in void context at -e line 1.
  Modification of a read-only value attempted at -e line 1.

Simpler examples give the expected warnings

  perl -we '${$1}'
  Useless use of a variable in void context at -e line 1.
  Use of uninitialized value at -e line 1.

  perl -we 'defined ${+undef}'
  Useless use of defined operator in void context at -e line 1.
  Use of uninitialized value at -e line 1.

This didn't happen in perl5.003 FWIW. Something to do with
autovivication of references to scalars?

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2003

From @floatingatoll

[RT_System - Wed Dec 13 02​:51​:31 2000]​:

Still in 8101....

    perl \-we 'defined $\{$1\}'

Still in 18374.

@p5pRT
Copy link
Author

p5pRT commented Jul 16, 2003

From @schwern

[coral - Sun Jul 6 15​:16​:33 2003]​:

[RT_System - Wed Dec 13 02​:51​:31 2000]​:

Still in 8101....

    perl \-we 'defined $\{$1\}'

Still in 18374.

Still in 5.8.1 RC2

@p5pRT
Copy link
Author

p5pRT commented Jul 13, 2005

From @schwern

Still in 25129.

$ bleadperl -wle 'defined ${$1}'
Useless use of defined operator in void context at -e line 1.
Modification of a read-only value attempted at -e line 1.

@p5pRT
Copy link
Author

p5pRT commented Oct 10, 2009

From @obra

On Tue Jul 12 19​:57​:31 2005, schwern wrote​:

Still in 25129.

$ bleadperl -wle 'defined ${$1}'
Useless use of defined operator in void context at -e line 1.
Modification of a read-only value attempted at -e line 1.

Still present in 5.11.0.

[jesse@​mar-adentro ~ (master)]$ /usr/local/bin/perl5.11.0 -wle 'defined
${$1}'
Useless use of defined operator in void context at -e line 1.
Modification of a read-only value attempted at -e line 1.

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2009

From @ikegami

I don't see how this is a bug. Attempting to autovivify a constant
should throw that error.

Autovivification occurs when dereferencing an undefined scalar when an
lvalue is expected.

By the way, there's nothing special about defined() or $1. Any lvalue
context and any undefined constant scalar will do.

----- BEGIN CODE -----
use strict;
use warnings;

use Readonly;
Readonly my $x;

eval { sub {}->( $$x ) }; print $@​ || "ok\n";
eval { sub {}->( @​$x ) }; print $@​ || "ok\n";
eval { $$x = "abc"; }; print $@​ || "ok\n";
eval { @​$x = (); }; print $@​ || "ok\n";
----- END CODE -----

----- BEGIN OUTPUT -----
Modification of a read-only value attempted at a.pl line 7
Modification of a read-only value attempted at a.pl line 8
Modification of a read-only value attempted at a.pl line 9
Modification of a read-only value attempted at a.pl line 10
----- END OUTPUT -----

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2009

From @davidnicol

this appears to be working as documented at
http​://search.cpan.org/~roode/Readonly-1.03/Readonly.pm
changing $x from its initial undefined value to be a reference would
mean writing that reference to it. with C<no strict 'refs'> does the
provided code successfully manipulate *{''} ? Is manipulating the
various slots in *{""} the desired behavior?

On Mon, Dec 14, 2009 at 4​:26 PM, Eric Brine via RT
<perlbug-followup@​perl.org> wrote​:

I don't see how this is a bug. Attempting to autovivify a constant
should throw that error.

Autovivification occurs when dereferencing an undefined scalar when an
lvalue is expected.

By the way, there's nothing special about defined() or $1. Any lvalue
context and any undefined constant scalar will do.

----- BEGIN CODE -----
use strict;
use warnings;

use Readonly;
Readonly my $x;

eval { sub {}->( $$x ) }; print $@​ || "ok\n";
eval { sub {}->( @​$x ) }; print $@​ || "ok\n";
eval { $$x = "abc";    }; print $@​ || "ok\n";
eval { @​$x = ();       }; print $@​ || "ok\n";
----- END CODE -----

----- BEGIN OUTPUT -----
Modification of a read-only value attempted at a.pl line 7
Modification of a read-only value attempted at a.pl line 8
Modification of a read-only value attempted at a.pl line 9
Modification of a read-only value attempted at a.pl line 10
----- END OUTPUT -----

--
Is it the time when there isn't time to discuss but there is time to act yet?

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2009

From @ikegami

On Wed, Dec 16, 2009 at 4​:29 PM, David Nicol <davidnicol@​gmail.com> wrote​:

this appears to be working as documented at
http​://search.cpan.org/~roode/Readonly-1.03/Readonly.pm<http​://search.cpan.org/%7Eroode/Readonly-1.03/Readonly.pm>
changing $x from its initial undefined value to be a reference would
mean writing that reference to it.

Exactly.

with C<no strict 'refs'> does the

provided code successfully manipulate *{''} ? Is manipulating the
various slots in *{""} the desired behavior?

No. That would require $x="" instead of $x=undef.

$ perl -e'$x = undef; $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x = SCALAR(0xa160880)
${""} =

$ perl -e'$x = ""; $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x =
${""} = abc

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2009

From @davidnicol

On Wed, Dec 16, 2009 at 3​:42 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

On Wed, Dec 16, 2009 at 4​:29 PM, David Nicol <davidnicol@​gmail.com> wrote​:

with C<no strict 'refs'> does the
provided code successfully manipulate *{''} ? Is manipulating the
various slots in *{""} the desired behavior?

No. That would require $x="" instead of $x=undef.

$ perl -e'$x = undef; $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x = SCALAR(0xa160880)
${""} =

$ perl -e'$x = "";    $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x =
${""} = abc

I am surprised. Is /this/ a bug?

--
Is it the time when there isn't time to discuss but there is time to act yet?

@p5pRT
Copy link
Author

p5pRT commented Dec 17, 2009

From @ikegami

On Thu, Dec 17, 2009 at 11​:34 AM, David Nicol <davidnicol@​gmail.com> wrote​:

On Wed, Dec 16, 2009 at 3​:42 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

On Wed, Dec 16, 2009 at 4​:29 PM, David Nicol <davidnicol@​gmail.com>
wrote​:

with C<no strict 'refs'> does the
provided code successfully manipulate *{''} ? Is manipulating the
various slots in *{""} the desired behavior?

No. That would require $x="" instead of $x=undef.

$ perl -e'$x = undef; $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x = SCALAR(0xa160880)
${""} =

$ perl -e'$x = ""; $$x = "abc"; print qq!\$x = $x\n\${""} = ${""}\n!'
$x =
${""} = abc

I am surprised. Is /this/ a bug?

That you can create a var named (empty string)? Perhaps, but I don't think
so. As far as I'm concerned, if you use symbolic references or play with the
symbol table, you are either already doing something stupid or you know what
you are doing. In neither case would filing this as a bug help.

In fact, the ability to create illegally named variables is used as a
feature by Perl. The debugger or something creates variables named like
"_<perlio.c" in main​::

Or maybe you are referring to the difference between undef and "". As far as
I'm concerned, it's appropriate that only undefined variables are
autovivified. Anything else is treated as a (symbolic or actual) reference.
C<< use strict 'refs'; >> will catch the symbolic references.

- ELB

@p5pRT
Copy link
Author

p5pRT commented Dec 18, 2009

From @davidnicol

On Thu, Dec 17, 2009 at 11​:39 AM, Eric Brine

Or maybe you are referring to the difference between undef and "". As far as
I'm concerned, it's appropriate that only undefined variables are
autovivified. Anything else is treated as a (symbolic or actual) reference.
C<< use strict 'refs'; >> will catch the symbolic references.

I expect undef to always stringify to the empty string, and I expect
reference notation to stringify. so, I guess when $x is undefined,
SYGILL{$x} would try to upgrade the undef to a real reference before
stringifying it, and the operation that surprised me was only
surprising because I had thought of reference dereference as a special
case of symbolic dereference, when symbolic dereference is really the
special case, outside of hash lookup, where undef will become empty
string.

So to force stringification for symbolic reference, doublequotes have
to be involved​: ${"$x"} with an undef $x instead of simply $$x, as $$x
upgrades an undef $x to a scalar reference.

# perl -le '$$x=123;$r="$x";print "$r symderefs to ${$r}"'
SCALAR(0x814faa8) symderefs to
#

i vaguely remember getting the idea at some point that the reference
strings -- like "SCALAR(0x814faa8)" above -- were supposed to work as
symbolic references to the same things. Which clearly isn't true, or
wasn't true at version 8.8 (debian stable.)

That isn't a bug either.

@p5pRT
Copy link
Author

p5pRT commented Mar 17, 2010

From @ikegami

Noone voiced any disagreement with my previous statement that Perl is
working as expected.

Furthermore, one can use "no autovivification;" to get the warning the
OP expects instead of the one that is naturally produced.

$ perl -we'no autovivification; my $d = defined( $$1 )'
Use of uninitialized value in scalar dereference at -e line 1.

$ perl -we'my $d = defined( $$1 )'
Modification of a read-only value attempted at -e line 1.

This ticket should be closed unless this ticket is suppose to be a about
the fact that dereferencing within the span of defined() (and exists())
can autovivify and it shouldn't, and that "no autovivification;" is not
an acceptable solution.

@p5pRT
Copy link
Author

p5pRT commented Mar 17, 2010

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

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