Skip Menu |

This queue is for tickets about the DBIx-Class CPAN distribution.

Report information
The Basics
Id: 71928
Status: resolved
Priority: 0/
Queue: DBIx-Class

People
Owner: Nobody in particular
Requestors: w.phillip.moore [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.08195
Fixed in: 0.08196



Subject: t/53lean_startup.t: Can't locate Tie/ExtraHash.pm
I'm getting the following test suite failure for 5.10.1, 5.12.4 and 5.14.2, on 32 and 64 bit builds on RHEL 5, Solaris 10 and AIX 6. [2011-10-25 16:54:20] Can't locate Tie/ExtraHash.pm in @INC (@INC contains: <long path Show quoted text
deleted>>) at t/53lean_startup.t line 10.
[2011-10-25 16:54:20] ...propagated at /efs/dist/perl5/core/5.14.2-build002/.exec/x86- 64.rhel.5/lib/perl5/base.pm line 94. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at (eval 31) line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at /efs/dist/perl5/namespace- clean/0.21/.exec/x86-64.rhel.5/5.14/lib/perl5/namespace/c\ lean.pm line 92. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at /var/tmp/perl5-DBIx-Class- 0.08195-build001-build/x86-64.rhel.5/5.14/source/DBIx-Cla\ ss-0.08195/blib/lib/DBIx/Class/Carp.pm line 18. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at /var/tmp/perl5-DBIx-Class- 0.08195-build001-build/x86-64.rhel.5/5.14/source/DBIx-Cla\ ss-0.08195/blib/lib/DBIx/Class/Exception.pm line 6. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at /var/tmp/perl5-DBIx-Class- 0.08195-build001-build/x86-64.rhel.5/5.14/source/DBIx-Cla\ ss-0.08195/blib/lib/DBIx/Class/Schema.pm line 6. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] ...propagated at /efs/dist/perl5/core/5.14.2-build002/.exec/x86- 64.rhel.5/lib/perl5/base.pm line 94. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at t/lib/DBICTest/Schema.pm line 4. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at t/lib/DBICTest.pm line 7. [2011-10-25 16:54:20] Compilation failed in require at t/53lean_startup.t line 10. [2011-10-25 16:54:20] BEGIN failed--compilation aborted at t/53lean_startup.t line 95. [2011-10-25 16:54:20] t/53lean_startup.t ............................... [2011-10-25 16:54:20] Dubious, test returned 2 (wstat 512, 0x200) [2011-10-25 16:54:20] No subtests run I do not understand what this script is doing, but Tie::ExtraHash is a package inside the Tie/Hash.pm file, and there isn't a separate Tie/ExtraHash.pm file to be found.
Subject: make_test.txt

Message body is not shown because it is too large.

I've found the root cause of this, and I'm very curious why noone else is seeing this error yet. Obviously, nothing in DBIx-Class refers to Tie::ExtraHash. That dependency actually comes from namespace::clean, which is used by DBIx::Class::Carp. In namespace::clean, the "right thing" is done to use Tie::ExtraHash as a base class: use Tie::Hash; use base 'Tie::ExtraHash'; This works because base->import does the following: eval "require $base"; die $@ if $@ && $@ !~ /^Can't locate .*? at \(eval/; However, in t/53lean_startup.t, because the require method is wrapped in the first BEGIN block, the error that's thrown is NOT "at (eval)" it is "at t/53lean_startup.t", the regexp fails to match, and base->import re-throws the error. I've reduced the problem to a very simple test case, which fails for every perl I've tried, on every platform: BEGIN { *CORE::GLOBAL::require = sub { CORE::require($_[0]); }; } use Tie::Hash; use base 'Tie::ExtraHash'; Run this, and you get: pmoore@Renegade$ perl ~/base.pl Can't locate Tie/ExtraHash.pm in @INC (@INC contains: /Users/pmoore/lib/perl5 /opt/local/lib/perl5/site_perl/5.12.3/darwin-multi-2level /opt/lo\ cal/lib/perl5/site_perl/5.12.3 /opt/local/lib/perl5/vendor_perl/5.12.3/darwin-multi-2level /opt/local/lib/perl5/vendor_perl/5.12.3 /opt/local/l\ ib/perl5/5.12.3/darwin-multi-2level /opt/local/lib/perl5/5.12.3 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl .) at /Users/pm\ oore/base.pl line 5. ...propagated at /opt/local/lib/perl5/5.12.3/base.pm line 94. BEGIN failed--compilation aborted at /Users/pmoore/base.pl line 10. That appears to be the root cause of this problem. The wrapped require method results in confusing base.pm, because the error doesn't appear to come from the eval of that string, ot appears to come from some other file, and the code dies. If you download and install: http://backpan.perl.org/authors/id/R/RI/RIBASUSHI/namespace-clean-0.20_01.tar.gz then that test passes fine. This is because in 0.20_01, Tie::ExtraHash is refered to via: ./lib/namespace/clean.pm: tie( %^H, 'Tie::ExtraHash', namespace::clean::_ScopeGuard- Show quoted text
>arm(shift) );
But in 0.21, this was changed to: ./lib/namespace/clean.pm: use base 'Tie::ExtraHash'; I have tried hacking in several workarounds, but in every case for which the hack "fixes" my test program above, it breaks something else in t/53lean_startup.t. For example, I can make the test script work if I do this: BEGIN { *CORE::GLOBAL::require = sub { eval { CORE::require($_[0]); }; if ( $@ ) { $@ =~ s{at\s+\S+}{at (eval 1)}gmsx; die $@; } }; } IOW, hack $@ so that it looks like it came from eval. However, if I add this to t/53lean_projects.t, I get an even stranger set of errors. [efsops@shou18l560-02 DBIx-Class-0.08195]$ perl -Mblib t/53lean_startup.t DBIx::Class::Schema::throw_exception(): Can't locate object method "table" via package "DBICTest::BaseResult" at t/lib/DBICTest/BaseResult.pm line 11. Compilation failed in require at (eval 1) line 10. ...propagated at /efs/dist/perl5/core/5.14.2- build002/.exec/powerpc32.aix.6/lib/perl5/base.pm line 94. BEGIN failed--compilation aborted at t/lib/DBICTest/Schema/Artist.pm line 4. Compilation failed in require at (eval 1) line 10. at /efs/dist/perl5/Class-C3- Componentised/1.001000/.exec/powerpc32.aix.6/5.14/lib/perl5/Class/C3/Componentised. pm line 155 Compilation failed in require at (eval 1) line 10. BEGIN failed--compilation aborted at t/lib/DBICTest.pm line 7. Compilation failed in require at (eval 1) line 10. BEGIN failed--compilation aborted at t/53lean_startup.t line 99. Clearly, that workaround is NOT general enough, although since require normally raises an exception, it's hard to understand why it doesn't. In any case, I don't really understand how to patch DBIx-Class to fix, or really just workaround, this issue. For now, I've downgraded namespace::clean to 0.20_01, but one of these days, I'll want/need to upgrade, so this will eventually need to be fixed.
Subject: Re: [rt.cpan.org #71928] t/53lean_startup.t: Can't locate Tie/ExtraHash.pm
Date: Wed, 26 Oct 2011 13:16:28 -0400
To: Phillip Moore via RT <bug-DBIx-Class [...] rt.cpan.org>
From: Peter Rabbitson <ribasushi [...] cpan.org>
On Wed, Oct 26, 2011 at 01:08:07PM -0400, Phillip Moore via RT wrote: Show quoted text
> Queue: DBIx-Class > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=71928 > > > I've found the root cause of this, and I'm very curious why noone else is seeing this error yet. > > Obviously, nothing in DBIx-Class refers to Tie::ExtraHash. That dependency actually comes > from namespace::clean, which is used by DBIx::Class::Carp. In namespace::clean, the "right > thing" is done to use Tie::ExtraHash as a base class: > > use Tie::Hash; > use base 'Tie::ExtraHash'; > > This works because base->import does the following: > > eval "require $base"; > die $@ if $@ && $@ !~ /^Can't locate .*? at \(eval/; > > However, in t/53lean_startup.t, because the require method is wrapped in the first BEGIN > block, the error that's thrown is NOT "at (eval)" it is "at t/53lean_startup.t", the regexp fails to > match, and base->import re-throws the error. > > I've reduced the problem to a very simple test case, which fails for every perl I've tried, on > every platform: > > BEGIN { > *CORE::GLOBAL::require = sub { > CORE::require($_[0]); > }; > } > > use Tie::Hash; > use base 'Tie::ExtraHash'; >
Fuck you base.pm. Ok 2 things here: 1) There was some work on this test done in the DBIC repo. Please checkout current master[1] and see if the issue has been fixed (the require() override is much much cleverer now) 2) Since someone *else* may fuck this up in weird and unknown ways, I am thinking to ship a version of n::c that sets @ISA instead of mucking with use base (given how n::c is a pretty central thing these days). I do not know if this is warranted yet, will ponder with interested parties. Thank you so very much for tracking this down, I am just as dumbfounded as you on why nobody else experiences this... Cheers
Subject: Re: [rt.cpan.org #71928] t/53lean_startup.t: Can't locate Tie/ExtraHash.pm
Date: Wed, 26 Oct 2011 14:14:35 -0400
To: bug-DBIx-Class [...] rt.cpan.org
From: Phillip Moore <w.phillip.moore [...] gmail.com>
I have an answer for why noone else has seen this yet.... I'm working on trying to reproduce the OTHER problem I reported yesterday, and the first thing I noticed was that t/53lean_startup.t was passing, when I was expecting it to fail. Huh? Well, I hacked base.pm in the standalone test setup I just built, and when t/53lean_projects.t runs, base.pm NEVER SEES Tie::ExtraHash passed to it. Well, if you look inside clean.pm, it's clear why. Tie::Hash and Tie::ExtraHash are only used if B::Hooks::EndOfScope is NOT installed. If it IS installed, then it is used, and the code that causes this problem is not called. My working test case was simply a build of perl5.14.2 along with ALL of the dependencies my app has, installed as a bundle using cpanp. Somehow, cpanp figured out that namespace::clean 021 requires B::Hooks::EndOfScope, but the META.yml file for namespace::clean doesn't list this at all. cpanp figures this out when by parsing the output of Makefile.PL (or possibly using MYMETA.yml? have to go look...), but the build system in the failing case is very different -- it is driven entirely by metadata found in META.yml files, so when I installed namespace::clean, it was NOT built and tested against B::Hooks::EndOfScope. So..... In this case, the reason noone else is seeing it is that I have made the mistake of depending on META.yml files having correct dependency information, and when they information is missing, I depend on the tests failing, so I can address the missing ones. This is an edge case, where the Makefile.PL tries to dynamically figure out what can and can not be depended on, and the result is that the META.yml file included with it has a PARTIAL but not a COMPLETE list of dependencies. Oddly, if you run "perl Makefile.PL", and let MYMETA.yml get generated, that correctly lists the B::Hooks::EndOfScope dependency as "required". However, if you then run "make manifest dist" to regenerate the META.yml file, it says nothing about it. It looks like I need to change my build system to prefer MYMETA.yml over META.yml, since I can recreate these when they are missing (people are STILL uploading stuff to CPAN with no META.yml files). There may or may be a way to change namespace-clean's Makefile.PL to get that dependency listed correctly in the META.yml file, but regardless, lots of other modules will have similar issues, so I need to code a solution into my build system. I think it's safe to say that you can close this ticket, although I suppose that since namespace::clean CAN be installed without B::Hooks::EndOfScope and work fine, and since DBIx::Class doesn't depend on it, it IS possible that someone will see this, but very unlikely. On Wed, Oct 26, 2011 at 1:16 PM, Peter Rabbitson via RT < bug-DBIx-Class@rt.cpan.org> wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=71928 > > > On Wed, Oct 26, 2011 at 01:08:07PM -0400, Phillip Moore via RT wrote:
> > Queue: DBIx-Class > > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=71928 > > > > > I've found the root cause of this, and I'm very curious why noone else is
> seeing this error yet.
> > > > Obviously, nothing in DBIx-Class refers to Tie::ExtraHash. That
> dependency actually comes
> > from namespace::clean, which is used by DBIx::Class::Carp. In
> namespace::clean, the "right
> > thing" is done to use Tie::ExtraHash as a base class: > > > > use Tie::Hash; > > use base 'Tie::ExtraHash'; > > > > This works because base->import does the following: > > > > eval "require $base"; > > die $@ if $@ && $@ !~ /^Can't locate .*? at \(eval/; > > > > However, in t/53lean_startup.t, because the require method is wrapped in
> the first BEGIN
> > block, the error that's thrown is NOT "at (eval)" it is "at
> t/53lean_startup.t", the regexp fails to
> > match, and base->import re-throws the error. > > > > I've reduced the problem to a very simple test case, which fails for
> every perl I've tried, on
> > every platform: > > > > BEGIN { > > *CORE::GLOBAL::require = sub { > > CORE::require($_[0]); > > }; > > } > > > > use Tie::Hash; > > use base 'Tie::ExtraHash'; > >
> > Fuck you base.pm. Ok 2 things here: > > 1) There was some work on this test done in the DBIC repo. Please checkout > current master[1] and see if the issue has been fixed (the require() > override is much much cleverer now) > > 2) Since someone *else* may fuck this up in weird and unknown ways, I am > thinking to ship a version of n::c that sets @ISA instead of mucking with > use base (given how n::c is a pretty central thing these days). I do not > know if this is warranted yet, will ponder with interested parties. > > Thank you so very much for tracking this down, I am just as dumbfounded as > you on why nobody else experiences this... > > Cheers > > >
On Wed Oct 26 13:08:05 2011, WPMOORE wrote: Show quoted text
> I've found the root cause of this, and I'm very curious why noone else > is seeing this error yet. > > Obviously, nothing in DBIx-Class refers to Tie::ExtraHash. That > dependency actually comes > from namespace::clean, which is used by DBIx::Class::Carp. In > namespace::clean, the "right > thing" is done to use Tie::ExtraHash as a base class: > > use Tie::Hash; > use base 'Tie::ExtraHash'; > > This works because base->import does the following: > > eval "require $base"; > die $@ if $@ && $@ !~ /^Can't locate .*? at \(eval/; > > However, in t/53lean_startup.t, because the require method is wrapped > in the first BEGIN > block, the error that's thrown is NOT "at (eval)" it is "at > t/53lean_startup.t", the regexp fails to > match, and base->import re-throws the error. > > I've reduced the problem to a very simple test case, which fails for > every perl I've tried, on > every platform: > > BEGIN { > *CORE::GLOBAL::require = sub { > CORE::require($_[0]); > }; > } > > use Tie::Hash; > use base 'Tie::ExtraHash'; >
Right, we eventually got to the bottom of this, but forgot to close the ticket.The problem was indeed in DBIC itself, because it did not do the require override properly. I nicked the correct way from Zefram's Lexical::SealRequireHints, and even abstracted it into a nicer interface. However I did not put it on CPAN as we couldn't agree with Zefram what is the sane way of going forward. I am putting all the relevant information here, hoping that maybe you will get this to CPAN-dom (it is a very very tricky thing to do right, and it ought to be properly encapsulated). This works: BEGIN { unshift @INC, 't/lib'; require DBICTest::Util::OverrideRequire; DBICTest::Util::OverrideRequire::override_global_require( sub { $_[0]->() }); } use Tie::Hash; use base 'Tie::ExtraHash'; And this is how it is implemented: https://metacpan.org/source/ARODLAND/DBIx-Class-0.08196/t/lib/DBICTest/Util/OverrideRequire.pm