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

$ISA[0] assignment does not work #13240

Open
p5pRT opened this issue Sep 15, 2013 · 5 comments
Open

$ISA[0] assignment does not work #13240

p5pRT opened this issue Sep 15, 2013 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 15, 2013

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

Searchable as RT119803$

@p5pRT
Copy link
Author

p5pRT commented Sep 15, 2013

From @cpansprout

$ ./perl -Ilib -e '$ISA[0] = foo'
Recursive inheritance detected in package 'main' at -e line 1.

$ ../perl.git/Porting/bisect.pl --end=v5.10.0 --target=miniperl -e '$ISA[0] = "foo"'
...
There are only 'skip'ped commits left to test.
The first bad commit could be any of​:
14f97ce
b0c482e
e1a479c
f40a715
9edc5bb
We cannot bisect more!
bisect run cannot continue any more
Died at ../perl.git/Porting/bisect.pl line 223.
That took 554 seconds

So this goes back to the mro changes in 5.10.

Perl is too trigger-happy when it comes to recursive inheritance.

One problem with that error message is that it doesn’t prevent anything bad from happening (like ‘Modification of a read-only value attempted’). It only happens *after* the bad inheritance has already been set up. (The same applies to class hierarchies incompatible with C3.)

So the error does not do that much good, even in an eval, since some other benign code might trip up on that same error.

Something tells me we have an architectural problem of sorts.

Obviously, if you are actually trying to call a method and you have @​Foo​::ISA = Foo, then the method call should croak.

But internal bookkeeping that happens at the time of @​ISA adjustment should probably simply be deferred if the hierarchy is nonsensical.


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.19.4​:

Configured by sprout at Mon Sep 9 00​:16​:24 PDT 2013.

Summary of my perl5 (revision 5 version 19 subversion 4) configuration​:
  Commit id​: d47819ff6f55bfaa4b7eddc66c6db7d7dfdec11c
  Platform​:
  osname=darwin, osvers=12.2.0, archname=darwin-2level
  uname='darwin pint.local 12.2.0 darwin kernel version 12.2.0​: sat aug 25 00​:48​:52 pdt 2012; root​:xnu-2050.18.24~1release_x86_64 x86_64 '
  config_args='-de -Dcc=gcc -Dusedevel -Doptimize=-ggdb3 -Aoptimize=-O0 -DDEBUGGING'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include',
  optimize='-ggdb3 -O0',
  cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)', 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='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib
  libs=-ldbm -ldl -lm -lutil -lc
  perllibs=-ldl -lm -lutil -lc
  libc=, so=dylib, useshrplib=false, libperl=libperl.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector'


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


Environment for perl 5.19.4​:
  DYLD_LIBRARY_PATH (unset)
  HOME=/Users/sprout
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/usr/bin​:/bin​:/usr/sbin​:/sbin​:/usr/local/bin​:/usr/local/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Nov 19, 2017

From zefram@fysh.org

Father Chrysostomos wrote​:

But internal bookkeeping that happens at the time of @​ISA adjustment
should probably simply be deferred if the hierarchy is nonsensical.

More simply, we could just make the linear_isa caching lazy in all
cases. That's an appealing idea. However, there are API implications.
The functions mro​::get_isarev() and mro​::is_universal() are defined to
indicate a given class's descendants. This knowledge arises from the
process of generating the linear_isa for each descendant. Internally
we use the isarev for cache invalidation, and for that purpose it
doesn't have to be a complete list of descendants​: it only has to
list those descendants whose cached linear_isa includes this class.
But the documentation of the public interfaces describes them as giving
information about the actual set of descendants, with no caveats about
reflecting only cached information.

So to make the caching lazy we'd have to either withdraw mro​::get_isarev()
and mro​::is_universal() or redocument them as having much more limited
utility. A deprecation cycle might be required. What we should do
here depends somewhat on how these functions are used in practice.
Can someone comment on that?

-zefram

@p5pRT
Copy link
Author

p5pRT commented Nov 19, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2017

From @cpansprout

On Sun, 19 Nov 2017 07​:39​:27 -0800, zefram@​fysh.org wrote​:

Father Chrysostomos wrote​:

But internal bookkeeping that happens at the time of @​ISA adjustment
should probably simply be deferred if the hierarchy is nonsensical.

More simply, we could just make the linear_isa caching lazy in all
cases. That's an appealing idea. However, there are API implications.
The functions mro​::get_isarev() and mro​::is_universal() are defined to
indicate a given class's descendants. This knowledge arises from the
process of generating the linear_isa for each descendant. Internally
we use the isarev for cache invalidation, and for that purpose it
doesn't have to be a complete list of descendants​: it only has to
list those descendants whose cached linear_isa includes this class.
But the documentation of the public interfaces describes them as giving
information about the actual set of descendants, with no caveats about
reflecting only cached information.

So to make the caching lazy we'd have to either withdraw mro​::get_isarev()
and mro​::is_universal() or redocument them as having much more limited
utility. A deprecation cycle might be required. What we should do
here depends somewhat on how these functions are used in practice.
Can someone comment on that?

MRO​::Compat provides its own get_isarev and is_universal when invoked on perl 5.8. It also has tests for get_isarev, which may need to be tweaked.

And the following modules use at least one of the two functions, usually get_isarev​:

Test​::Class
Class​::LOP
MR​::IProto
Plack​::Middleware​::Debug​::Catalyst​:PluginCache
Test​::Mini​::Runner

I have not looked into them in detail.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Nov 21, 2017

From [Unknown Contact. See original ticket]

On Sun, 19 Nov 2017 07​:39​:27 -0800, zefram@​fysh.org wrote​:

Father Chrysostomos wrote​:

But internal bookkeeping that happens at the time of @​ISA adjustment
should probably simply be deferred if the hierarchy is nonsensical.

More simply, we could just make the linear_isa caching lazy in all
cases. That's an appealing idea. However, there are API implications.
The functions mro​::get_isarev() and mro​::is_universal() are defined to
indicate a given class's descendants. This knowledge arises from the
process of generating the linear_isa for each descendant. Internally
we use the isarev for cache invalidation, and for that purpose it
doesn't have to be a complete list of descendants​: it only has to
list those descendants whose cached linear_isa includes this class.
But the documentation of the public interfaces describes them as giving
information about the actual set of descendants, with no caveats about
reflecting only cached information.

So to make the caching lazy we'd have to either withdraw mro​::get_isarev()
and mro​::is_universal() or redocument them as having much more limited
utility. A deprecation cycle might be required. What we should do
here depends somewhat on how these functions are used in practice.
Can someone comment on that?

MRO​::Compat provides its own get_isarev and is_universal when invoked on perl 5.8. It also has tests for get_isarev, which may need to be tweaked.

And the following modules use at least one of the two functions, usually get_isarev​:

Test​::Class
Class​::LOP
MR​::IProto
Plack​::Middleware​::Debug​::Catalyst​:PluginCache
Test​::Mini​::Runner

I have not looked into them in detail.

--

Father Chrysostomos

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