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

DFS does not respect superclasses’ MROs #11821

Open
p5pRT opened this issue Dec 25, 2011 · 4 comments
Open

DFS does not respect superclasses’ MROs #11821

p5pRT opened this issue Dec 25, 2011 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 25, 2011

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

Searchable as RT106998$

@p5pRT
Copy link
Author

p5pRT commented Dec 25, 2011

From @cpansprout

#!perl

# a
# / \
# b c
# \ /
# d

@​d​::ISA = qw 'b c';
@​b​::ISA = @​c​::ISA = 'a';

package d { use mro 'c3' }

package subclass { @​ISA = 'd'; }

$\="\n";
print for @​{mro'get_linear_isa 'd'};
print "----";
print for @​{mro'get_linear_isa 'subclass'};

__END__

The output shows that a c3 class fails the empty subclass test, because the subclass, which uses dfs by default, imposes that on its superclasses.

I think this is a flawed model. It means that no existing module hierarchies can switch over to c3 without breaking subclasses.

I think dfs mro linearisation needs to use the mro linearisations of its parents, instead of traversing all the superclasses itself.

Likewise I think c3 needs to be modified. It may not follow the c3 algorithm any more, but right now it�s impossible to use the c3 mro in the example above if class �a� happens to have dfs diamond inheritance from its superclasses. (Maybe the c3 algorithm should treat any class that does not use c3 as a �black box�​: it just takes the mro linearisation from that class and considers it a list of immediate superclasses.)

Likewise, next​::method should respect each class�s mro.

Otherwise, the current mro system is more a curiosity than anything else.

It�s not possible to use mro plugins to store the list of superclasses somewhere other than @​ISA.

Right now, to subclass a random class, one has to �use mro(); use mro mro​::get_mro $super�. Easy things should be simple and vice versa.


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.15.5​:

Configured by sprout at Sun Dec 18 11​:26​:14 PST 2011.

Summary of my perl5 (revision 5 version 15 subversion 5) configuration​:
  Snapshot of​: 5dca8ed
  Platform​:
  osname=darwin, osvers=10.5.0, archname=darwin-2level
  uname='darwin pint.local 10.5.0 darwin kernel version 10.5.0​: fri nov 5 23​:20​:39 pdt 2010; root​:xnu-1504.9.17~1release_i386 i386 '
  config_args='-de -Dusedevel -DDEBUGGING=-g'
  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 -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include',
  optimize='-O3 -g',
  cppflags='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.2.1 (Apple Inc. build 5664)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  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 =' -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'

Locally applied patches​:
 


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


Environment for perl 5.15.5​:
  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/X11/bin​:/usr/local/bin
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2012

From @doy

On Sun, Dec 25, 2011 at 02​:16​:28PM -0800, Father Chrysostomos wrote​:

I think this is a flawed model. It means that no existing module
hierarchies can switch over to c3 without breaking subclasses.

I think dfs mro linearisation needs to use the mro linearisations of
its parents, instead of traversing all the superclasses itself.

Likewise I think c3 needs to be modified. It may not follow the c3
algorithm any more, but right now it�s impossible to use the c3 mro in
the example above if class �a� happens to have dfs diamond inheritance
from its superclasses. (Maybe the c3 algorithm should treat any class
that does not use c3 as a â��black boxâ��​: it just takes the mro
linearisation from that class and considers it a list of immediate
superclasses.)

Likewise, next​::method should respect each classâ��s mro.

Otherwise, the current mro system is more a curiosity than anything
else.

It�s not possible to use mro plugins to store the list of superclasses
somewhere other than @​ISA.

Right now, to subclass a random class, one has to �use mro(); use mro
mro​::get_mro $superâ��. Easy things should be simple and vice versa.

I don't think the concept of a class hierarchy having multiple MROs even
makes any sense. It works fine conceptually for things like DFS, because
DFS is a recursive algorithm, but C3 is not a recursive algorithm. What
does it even mean to set a class's MRO to C3 if all of its parents use
DFS? The issue is that the MRO is a property of the lookup across the
hierarchy as a whole, not of a given class. I think perl should reject
any attempt to mix MROs within a given class hierarchy.

-doy

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2017

From zefram@fysh.org

doy is right, mixing MROs doesn't make much sense. The entire method
lookup process on one class needs to use a single MRO. But we could
improve things by making the MRO of a class default to the MRO of its
superclasses; that would fix the empty-subclass case. (There are details
to sort out about conflicting superclasses, order of initialisation,
deprecation cycle, and suchlike, but I don't see anything worrying.)
How does that sound to you?

-zefram

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