Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Catalyst reload, 'use parent' and mro c3 (UPD: NOT Catalyst)

by vsespb (Chaplain)
on Dec 23, 2015 at 18:53 UTC ( [id://1151073]=perlquestion: print w/replies, xml ) Need Help??

vsespb has asked for the wisdom of the Perl Monks concerning the following question:

UPD: all true, except the thing which reload modules in dev mode was not Catalyst's but our code, which simply "do $modulefile".

I am running Catalyst in dev mode. It's able to reload packages when package's file modified.

One of my packages:

package SRS::MyTest; use parent 'File::Find'; our @ISA; BEGIN { print STDERR "HEREISIT @ISA\n"}; 1;

If i modify it, catalyst will reload it, and then I see in console:

HEREISIT File::Find File::Find - /somepath/MyTest.pm reloaded 2343

That means File::Find is now twice in @ISA. Not a big problem until you use MRO C3

With mro C3 it fails with error: "Inconsistent hierarchy during C3 merge of class"

I believe these are separate part of this problem:

  • 'use parent' will put module to @ISA twice if called twice ('use base' won't)
  • mro C3 cannot live with same module specified twice
  • Catalyst reloading modules without clearing @ISA first

PoC of problem without catalyst:

$ cat s1.pl package XXX; BEGIN { require mro; mro::set_mro( "XXX", 'c3' ); } use parent qw( File::Find ); use parent qw( File::Find ); 1; $ perl s1.pl Inconsistent hierarchy during C3 merge of class 'XXX': current merge results [ XXX, ] merging failed on 'File::Find' at /usr/share/perl/5.14/parent.pm l +ine 26. BEGIN failed--compilation aborted at s1.pl line 4.

Questions are:

  • How to workaround this (to use catalyst @ dev, mro c3, 'use parent' at same time)?
  • Is this Catalyst bug?
  • How other people live with this? Am I first who ran into this?
  • Where Catalyst's reloading code is described (or how to see it)?

Replies are listed 'Best First'.
Re: Catalyst reload, 'use parent' and mro c3
by Anonymous Monk on Dec 23, 2015 at 19:35 UTC
    Probably just clear @ISA manually?
    package SRS::MyTest; our @ISA; BEGIN { @ISA = (); } use parent 'File::Find'; BEGIN { print STDERR "HEREISIT @ISA\n"}; 1;
    Where Catalyst's reloading code is described (or how to see it)?
    Don't know about Catalyst, but it's probably something like:
    delete $INC{'XXX.pm'}; require 'XXX.pm';
    in fact:
    # main.pl use XXX (); delete $INC{'XXX.pm'}; require 'XXX.pm';
    # XXX.pm package XXX; use parent 'File::Find'; our @ISA; BEGIN { print STDERR "HEREISIT @ISA\n"}; 1;
    that does just that
    $ perl main.pl HEREISIT File::Find HEREISIT File::Find File::Find
      Probably just clear @ISA manually?
      Yes, that would work. Sad that I should insert this line too all of hundreds of files.
        Well, you can fix parent.pm instead... it's a very simple module:
        package parent; use strict; use vars qw($VERSION); $VERSION = '0.232'; sub import { my $class = shift; my $inheritor = caller(0); if ( @_ and $_[0] eq '-norequire' ) { shift @_; } else { for ( my @filename = @_ ) { if ( $_ eq $inheritor ) { warn "Class '$inheritor' tried to inherit from itself\n"; } s{::|'}{/}g; require "$_.pm"; # dies if the file is not found } } { no strict 'refs'; my %ISA = map { $_ => 1 } @{"$inheritor\::ISA"}; for (@_) { push @{"$inheritor\::ISA"}, $_ if not $ISA{$_}; } }; } 1;
        just put it somewhere in @INC before the standard one, and let us know if it works :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1151073]
Approved by Laurent_R
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (2)
As of 2024-04-19 18:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found