Problem loading Method::Signatures when Moose::Roles is involved #41

Closed
Potatohead opened this Issue Oct 26, 2011 · 34 comments

Comments

Projects
None yet
9 participants
Contributor

Potatohead commented Oct 26, 2011

This gist implements the problem

There seems to be a problem with loading Method::Signatures when roles get involved in the order things are getting loaded. perl -c on OuterUserWorks.pm goes fine, but on OuterUserBroken.pm I get

Couldn't load class (InnerRole) because: Devel::Pragma: scope overflow at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Devel/Pragma.pm line 34.
BEGIN failed--compilation aborted at InnerRole.pm line 3.
Compilation failed in require at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Class/MOP.pm line 117.
 at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Class/MOP.pm line 123
        Class::MOP::__ANON__('Devel::Pragma: scope overflow at /home/cmckay/perl5/perlbrew/...') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/Try/Tiny.pm line 100
        Try::Tiny::try('CODE(0x8ab3e40)', 'Try::Tiny::Catch=REF(0x924c2f8)') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Class/MOP.pm line 128
        Class::MOP::load_first_existing_class('InnerRole') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Class/MOP.pm line 140
        Class::MOP::load_class('InnerRole', undef) called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Moose/Util.pm line 131
        Moose::Util::_apply_all_roles('Moose::Meta::Class=HASH(0x9205650)', undef, 'InnerRole') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Moose/Util.pm line 98  
        Moose::Util::apply_all_roles('Moose::Meta::Class=HASH(0x9205650)', 'InnerRole') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Moose.pm line 65
        Moose::with('Moose::Meta::Class=HASH(0x9205650)', 'InnerRole') called at /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi/Moose/Exporter.pm line 356
        Moose::with('InnerRole') called at OuterImplementor.pm line 4
        require OuterImplementor.pm called at OuterUserBroken.pm line 4
        OuterUserBroken::BEGIN() called at OuterImplementor.pm line 0
        eval {...} called at OuterImplementor.pm line 0
Compilation failed in require at OuterUserBroken.pm line 4.
BEGIN failed--compilation aborted at OuterUserBroken.pm line 4.

Moving the Method::Signatures load to after the class using the role as seen in OuterUserWorks.pm makes all the problems go away. Originally came across this issue using Method::Signatures::Modifiers with MooseX::Declare and eventually reduced it to this implementation of the error. Unfortunately The magic of all these mixed together is beyond my understanding so I can't figure out any more than it's broken in this manner.

Tested on 2 platforms:

Summary of my perl5 (revision 5 version 14 subversion 0) configuration:

  Platform:
    osname=linux, osvers=2.6.18-238.9.1.el5, archname=i686-linux-thread-multi
    uname='linux cmckay.devve.iseek.com.au 2.6.18-238.9.1.el5 #1 smp tue apr 12 18:10:56 edt 2011 i686 i686 i386 gnulinux '
    config_args='-de -Dprefix=/home/cmckay/perl5/perlbrew/perls/perl-5.14.0 -Dusethreads'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.1.2 20080704 (Red Hat 4.1.2-50)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.5.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'


Characteristics of this binary (from libperl): 
  Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
                        PERL_PRESERVE_IVUV USE_ITHREADS USE_LARGE_FILES
                        USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API
  Built under linux
  Compiled at May 16 2011 11:27:19
  %ENV:
    PERLBREW_PATH="/home/cmckay/perl5/perlbrew/bin:/home/cmckay/perl5/perlbrew/perls/perl-5.14.0/bin"
    PERLBREW_PERL="perl-5.14.0"
    PERLBREW_ROOT="/home/cmckay/perl5/perlbrew"
    PERLBREW_VERSION="0.20"
    PERL_AUTOINSTALL="--alldeps"
  @INC:
    /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/i686-linux-thread-multi
    /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0
    /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/5.14.0/i686-linux-thread-multi
    /home/cmckay/perl5/perlbrew/perls/perl-5.14.0/lib/5.14.0
    .

with

  • Method::Signatures 20111020
  • Moose 2.0205

and

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=linux, osvers=2.6.18-53.el5,
    archname=x86_64-linux-thread-multi
    uname='linux builder10.centos.org 2.6.18-53.el5 #1 smp mon nov 12
    02:14:55 est 2007 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall
    -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
    --param=ssp-buffer-size=4 -m64 -mtune=generic -Dversion=5.8.8
    -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc
    -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr
    -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64
    -Dprivlib=/usr/lib/perl5/5.8.8
    -Dsitelib=/usr/lib/perl5/site_perl/5.8.8
    -Dvendorlib=/usr/lib/perl5/vendor_perl/5.8.8
    -Darchlib=/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi
    -Dsitearch=/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
    -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi
    -Darchname=x86_64-linux-thread-multi -Dvendorprefix=/usr
    -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads
    -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm
    -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio
    -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly
    -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto
    -Ud_endhostent_r_proto -Ud_sethostent_r_proto
    -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto
    -Ud_endservent_r_proto -Ud_setservent_r_proto
    -Dinc_version_list=5.8.7 5.8.6 5.8.5 -Dscriptdir=/usr/bin'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define
    usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=define uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
    -pipe -Wdeclaration-after-statement -I/usr/local/include
    -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
    -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe
    -Wdeclaration-after-statement -I/usr/local/include
    -I/usr/include/gdbm'
    ccversion='', gccversion='4.1.2 20080704 (Red Hat 4.1.2-50)',
    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='gcc', ldflags =''
    libpth=/usr/local/lib64 /lib64 /usr/lib64
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread
    -lc
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
    -Wl,-rpath,/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall
    -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
    --param=ssp-buffer-size=4 -m64 -mtune=generic'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
                        PERL_MALLOC_WRAP USE_64_BIT_ALL USE_64_BIT_INT
                        USE_ITHREADS USE_LARGE_FILES USE_PERLIO
                        USE_REENTRANT_API
  Built under linux
  Compiled at Jun 13 2011 05:55:31
  %ENV:
    PERL5LIB="/home/bkolera/lib/perl5/lib/perl5/x86_64-linux-thread-multi:/home/bkolera/lib/perl5/lib/perl5"
    PERL_LOCAL_LIB_ROOT="/home/bkolera/lib/perl5"
    PERL_MB_OPT="--install_base /home/bkolera/lib/perl5"
    PERL_MM_OPT="INSTALL_BASE=/home/bkolera/lib/perl5"
  @INC:
    /home/bkolera/lib/perl5/lib/perl5/x86_64-linux-thread-multi
    /home/bkolera/lib/perl5/lib/perl5/x86_64-linux-thread-multi
    /home/bkolera/lib/perl5/lib/perl5
    /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.8
    /usr/lib/perl5/site_perl
    /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.8
    /usr/lib/perl5/vendor_perl
    /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi
    /usr/lib/perl5/5.8.8
    .

with

  • Method::Signatures 20110923.1726
  • Moose 2.0007
Contributor

barefootcoder commented Oct 26, 2011

I will try to take a look at this tomorrow, but I'm not 100% sure on the inner workings of Devel::Pragma myself, so I may have to pass it off to Schwern. But I'll try.

Contributor

barefootcoder commented Oct 28, 2011

It looks like something is nested that oughtn't be, but I haven't yet figured out how. The error is generated within the XS for Devel::Pragma, and it seems to indicate that xs_enter is being called for a second time before xs_leave is called for the first. Now, since xs_leave is called by on_scope_end, I'm not even entirely sure when that's supposed to happen. I'm going to have to do some more debugging tomorrow, but, in the meantime, if Schwern (or anyone else) has any thoughts shaken loose by this general description of the problem, I'd certainly love to hear 'em.

Contributor

barefootcoder commented Oct 28, 2011

Okay, it appears that on_scope_end means "on package scope end" (as opposed to "on block scope end"), and, even then, it ain't the current package, or even the calling package, but the package two levels up. Gist to demonstrate.

With the end result that when you do this:

use OuterImplementor;
use Method::Signatures;

it works, because the on_scope_end hook defined by Devel::Pragma inside Method::Signatures's import (from InnerRole) has fired by the time it gets back to the outermost package and hits Method::Signatures again.

However, when you reverse it:

use Method::Signatures;
use OuterImplementor;

the on_scope_end hook from the first Method::Signatures's import isn't going to fire until the outermost file is done compiling altogether. So when InnerRole comes along and calls Method::Signatures::import again, kaboom.

Now, whether this is a problem with Devel::Pragma or how we're using it, I can't say. I think at this point I'm going to have to toss it over to Schwern.

Contributor

Potatohead commented Oct 29, 2011

That explains things. Thanks for taking the time to look at this.

Contributor

schwern commented Oct 30, 2011

I don't know much about the guts of Devel::Pragma. Maybe @chocolateboy could have a look at how we're using it?

I'll take a look.

Is there a quick fix for this (or can I ignore it for the purposes of this issue)?

#   Failed test 'call with good value for paramized_sref passes'
#   at t/typeload_moose.t line 35.
# died: In call to Foo::Bar::check_paramized_sref(), the type ScalarRef[Num] is unrecognized (looks like it doesn't parse correctly) at t/typeload_moose.t line 35.

#   Failed test 'call with bad value for paramized_sref dies'
#   at t/typeload_moose.t line 37.
# expecting: Regexp ((?-xism:\AIn\ call\ to\ Foo\:\:Bar\:\:check_paramized_sref\(\)\,\ the\ \'bar\'\ parameter\ \(\"SCALAR\(0x9d9e848\)\"\)\ is\ not\ of\ type\ ScalarRef\[Num\]\ at\ ))
# found: In call to Foo::Bar::check_paramized_sref(), the type ScalarRef[Num] is unrecognized (looks like it doesn't parse correctly) at t/typeload_moose.t line 36.
# Looks like you failed 2 tests of 4.
t/typeload_moose.t .............

perl 5.10.1, Linux (Ubuntu 10.10)

Contributor

schwern commented Oct 30, 2011

@chocolateboy That looks like some change to a Moose error message. It's unrelated. What version of Moose are you using?

We're using Devel::Pragma so we can have lexical effect and yet support 5.8. Specifically the compile_at_BEGIN flag. Also because it apparently made it much easier to get the caller's hints, rather than having to guess how far up the stack to look. I guess mucking with hints outside of import() is not encouraged?

The only function we're using is my_hints(). Called once in import to set the METHOD_SIGNATURES_compile_at_BEGIN flag and then every time a function is compiled to check if it should be begin lifted (see _do_compile_at_BEGIN).

Contributor

barefootcoder commented Oct 30, 2011

@chocolateboy That looks like some change to a Moose error message. It's unrelated. What version of Moose are you using?

Well, I would say it looks like your Moose is so old it doesn't have the feature we're attempting to exercise. Tell me what version of Moose you have and I'll up the prerequisite and that should theoretically fix it. (Surprised we haven't seen this from CPAN Testers.)

But, yes, as Scwhern says, it's not relevant to the Devel::Pragma issue. Assuming there even is a Devel::Pragma issue; as I said above, it might just be that we're not using it correctly.

What version of Moose are you using?

Tell me what version of Moose you have

Good point: I have a 1.15 in ~/perl, but the (cpanm) test may have run against the system 0.95. Time I upgraded.

I guess mucking with hints outside of import() is not encouraged?

As long as you're not calling it at runtime it should work.

I'll take another look.

Contributor

schwern commented Oct 30, 2011

On 2011.10.30 12:24 PM, chocolateboy wrote:

I guess mucking with hints outside of import() is not encouraged?

As long as you're not calling it at runtime it should work.

It's called while Devel::Declare is doing its thing, so that should be compile
time.

Contributor

barefootcoder commented Oct 30, 2011

Good point: I have a 1.15 in ~/perl, but the (cpanm) test may have run against the system 0.95. Time I upgraded.

Oh yeah ... Moose isn't a requirement, so we're not specifying a minimum version.

@schwern: Should I add a recommends section to the Build.PL to address this? I can try to pin down what the min version is that handles the ScalarRef parameterized type; it's as good a watermark as any, I reckon.

EDIT: It's 0.96, according to the Moose Changes file.

Contributor

schwern commented Oct 30, 2011

On 2011.10.30 12:53 PM, Buddy Burden wrote:

Oh yeah ... Moose isn't a requirement, so we're not specifying a minimum version.

@schwern: Should I add a recommends section to the Build.PL to address this?
I can try to pin down what the min version is that handles the ScalarRef
parameterized type; it's as good a watermark as any, I reckon.

Yeah, that's a good idea.

@barefootcoder barefootcoder added a commit that referenced this issue Oct 30, 2011

@barefootcoder barefootcoder added "recommends" section for Moose
this is the minimum version of Moose that will compile the ScalarRef[] type
this came up as a side-issue when investigating GitHub #41
134422f
Contributor

barefootcoder commented Nov 21, 2011

Is there any movement on this issue?

It's on my TODO list.

Contributor

barefootcoder commented Nov 21, 2011

It's on my TODO list.

Awesome; thanx!

ruz commented Jan 4, 2012

Hi,

Smaller reproducible case without moose: https://gist.github.com/1559592

Contributor

barefootcoder commented Jan 4, 2012

@ruz: Thanks for the additional test case. We're waiting for chocolateboy to have a chance to look at it. Alternatively, do you have any ideas about how to work around the issue?

Thanks for the simplified test case. Is it meant to trigger the scope error in Devel::Pragma? I'm not getting an error running script.pl.

Method::Signatures: 20111125
Devel::Pragma: 0.54
perl 5.10.1
Ubuntu 10.10

ruz commented Jan 6, 2012

@chocolateboy

ruz@new-mac tmp $ perl script.pl

Devel::Pragma: scope overflow at /opt/local/lib/perl5/site_perl/5.14.1/darwin-thread-multi-2level/Devel/Pragma.pm line 34.
BEGIN failed--compilation aborted at Bar.pm line 4.
Compilation failed in require at MyBase.pm line 15.
BEGIN failed--compilation aborted at Foo.pm line 4.
Compilation failed in require at script.pl line 3.
BEGIN failed--compilation aborted at script.pl line 3.

M::S from repository
Devel::Pragma: 0.54
perl 5.14.1 for darwin-thread-multi-2level
MacOS Snow Leopard

Contributor

melo commented Apr 24, 2012

Small comment to enable watching this issue, I also have this problem.

Contributor

barefootcoder commented Jun 4, 2012

Just thought I'd ping @chocolateboy and see if he's had a chance to take a look at this yet.

Not yet, sorry. This also breaks mysubs, so it's on my radar.

jberger commented Oct 24, 2012

Just fyi, perhaps this will help diagnose. I had gotten the same error when I had modules like

package Physics::UEMColumn::Accelerator;

use Moose;
use namespace::autoclean;

use Method::Signatures;

BEGIN { extends 'Physics::UEMColumn::Element'; }

method field () {
  return 0;
}

__PACKAGE__->meta->make_immutable;

1;

But when I switched the order of use Method::Signatures; and BEGIN { extends 'Physics::UEMColumn::Element'; } (i.e. now do the extends first) the problem went away. Perhaps a similar load order issue is affecting your problems?

pjf commented Oct 1, 2013

Github needs a way that I can add myself as a watcher, but without adding some lame zero-content comment. :)

Contributor

barefootcoder commented Oct 1, 2013

Github needs a way that I can add myself as a watcher, but without adding some lame zero-content comment. :)

Well, possibly, but then the fact that you made a comment reminds me to ping @chocolateboy again to see if he ever had a chance to look at this problem. :-)

I'll take a look at the weekend. Feel free to nag me if I forget :-)

Contributor

barefootcoder commented Oct 1, 2013

I'll take a look at the weekend. Feel free to nag me if I forget :-)

Thanx man, and will do! :-)

I've just checked in a new version of Devel::Pragma (0.60). Could someone check it to see if the problem still persists?

Kulag commented Oct 11, 2013

I tested both of the test cases, and both worked correctly with 0.60. Thanks!

pjf commented Oct 13, 2013

Confirming that my development exobrain code is much happier with 0.60. Thanks, @chocolateboy ! I'd be delighted to see that up on the CPAN. :)

Contributor

barefootcoder commented Oct 13, 2013

Both ruz's simplified test case and potatohead's original work for me with Devel::Pragma 0.60. @chocolateboy, I'd say you should get this up on CPAN, and then I'll just increase the minimum version Method::Signatures requires for DP, and we should be able to put this one to bed. :-)

Thanks. It should be on CPAN shortly.

Contributor

barefootcoder commented Feb 24, 2014

Fixed by 20140224.

techman83 referenced this issue in techman83/WebService-Strava3 Aug 29, 2014

Closed

Set minimum versions to fix CPAN Testers failures #10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment