Skip to content

feat(moose): Phase A + Phase C-mini — HasCompiler stub + Class::MOP shim#570

Closed
fglock wants to merge 1 commit intomasterfrom
feature/moose-phase-abc
Closed

feat(moose): Phase A + Phase C-mini — HasCompiler stub + Class::MOP shim#570
fglock wants to merge 1 commit intomasterfrom
feature/moose-phase-abc

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 27, 2026

Summary

Implements the next phases of dev/modules/moose_support.md:

  • Phase A — deterministic ExtUtils::HasCompiler stub
    (src/main/perl/lib/ExtUtils/HasCompiler.pm). Always reports "no
    compiler", instead of relying on $Config{usedl} happening to be
    empty.
  • Phase C-miniClass::MOP shim (src/main/perl/lib/Class/MOP.pm)
    with class_of, get_metaclass_by_name, store_metaclass_by_name,
    remove_metaclass_by_name, does_metaclass_exist,
    get_all_metaclasses (and friends), get_code_info (via B),
    is_class_loaded, load_class, load_first_existing_class. Returns
    "no metaclass" everywhere — the correct answer under the
    Moose-as-Moo shim.

The previous behavior was a hard Undefined subroutine &Class::MOP::class_of called the moment Moo's _Utils::_load_module
hit a not-installed dependency on a class that already had Moose.pm
loaded (which our shim arranges at startup, by design).

Also updates dev/modules/moose_support.md with:

  • A new column in the baseline table reflecting the post-refcount/DESTROY
    state (was missing — the headline numbers had drifted from ~29 /
    370 / 246 to 35 / 372 / 244).
  • A third column for this PR's results.
  • Phase A / Phase C-mini marked done in the progress tracker.

Effect on ./jcpan -t Moose (Moose 2.4000)

Metric Before After
Files executed 478 478
Assertions executed 616 667
Fully passing files 35 36
Partially passing files 94 98
Compile/load fail (no tests) 349 344
Assertions ok 372 419
Assertions fail 244 248

Net: +51 assertions executed, +47 newly pass, +1 fully-green file.
The four extra "failures" are upstream tests that previously bailed
before reaching their assertion phase and now reach it; none are
real regressions.

Test plan

  • make — full unit suite passes (no regressions on either
    backend).
  • ./jperl -MExtUtils::HasCompiler=can_compile_loadable_object -e 'print can_compile_loadable_object(quiet=>1) ? "yes" : "no"'
    no.
  • ./jperl -MClass::MOP -e 'print Class::MOP::class_of("NoSuch") // "undef"'undef.
  • ./jperl -MClass::MOP -e 'print join(" ", Class::MOP::get_code_info(\&Class::MOP::class_of))'
    Class::MOP class_of.
  • ./jperl -MMoose -e 'package P { use Moose; has x => (is=>"rw") }; print P->new(x=>42)->x'42.
  • ./jcpan -t Moose — numbers above; saved in
    /tmp/moose_test2.txt.

What's intentionally not in this PR

  • Phase B (strip XS keys in WriteMakefile). Not yet needed because
    we're not yet trying to install upstream Moose.
  • Phase C-full / Phase D (real Class::MOP::Class instances, port
    of pure-Perl Moose). Tracked in the design doc; would unblock another
    big chunk of failing tests but is a much larger effort.

Generated with Devin

- Add deterministic ExtUtils::HasCompiler stub
  (src/main/perl/lib/ExtUtils/HasCompiler.pm). Always answers "no" to
  can_compile_loadable_object / can_compile_static_library /
  can_compile_extension. Replaces reliance on $Config{usedl} happening
  to be empty.

- Add Class::MOP shim (src/main/perl/lib/Class/MOP.pm) providing
  class_of, get_metaclass_by_name, store_metaclass_by_name,
  remove_metaclass_by_name, does_metaclass_exist,
  get_all_metaclasses (and friends), get_code_info (via B),
  is_class_loaded, load_class, load_first_existing_class. Returns
  "no metaclass" everywhere — the correct answer under the
  Moose-as-Moo shim. Previously Moo's _Utils::_load_module would
  hard-die with "Undefined subroutine &Class::MOP::class_of" the
  moment $INC{"Moose.pm"} was set, which our shim does at startup.

- Update dev/modules/moose_support.md with the new baseline column
  and mark Phase A / Phase C-mini done in the progress tracker.

Effect on `./jcpan -t Moose` (Moose 2.4000 upstream test suite vs.
the shim):

| Metric                        | Before | After |
|-------------------------------|-------:|------:|
| Files executed                |    478 |   478 |
| Assertions executed           |    616 |   667 |
| Fully passing files           |     35 |    36 |
| Partially passing files       |     94 |    98 |
| Compile/load fail (no tests)  |    349 |   344 |
| Assertions ok                 |    372 |   419 |
| Assertions fail               |    244 |   248 |

Net: +51 assertions executed, +47 newly pass, +1 fully-green file,
no regressions in `make` (full unit test suite passes).

See dev/modules/moose_support.md for the broader phase plan.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
fglock added a commit that referenced this pull request Apr 27, 2026
After two iterative shim-widening PRs (#570, #572), the original
phase plan ("ship Quick path, then do A→B→D") needs revision. The
shim approach has paid out much faster than a full pure-Perl port
would have, so the doc now:

1. Records concrete lessons learned (compile-time stubs are
   high-leverage; pre-loading matters as much as having stubs;
   BAIL_OUT is a hidden multiplier; the gap is method surface, not
   metaclass semantics; stubs need correct @isa).

2. Replaces the stale "Decision needed" section with a concrete,
   data-driven Phase 3+ plan, sized against the actual remaining
   failure counts in the latest run:

   - Phase 3 (rich Moose::_FakeMeta + next batch of stubs +
     TypeConstraint isa fix) — ~1 day; expected payoff +15–25 green
     files / +200–500 newly passing assertions.
   - Phase 4 (hook into Moo's attribute store from FakeMeta) — ~2
     days; gives Test::Moose::has_attribute_ok real semantics.
   - Phase 5 (Moose::Util::MetaRole::apply_metaroles) — ~1 day.
   - Phase 6 (full Moose::Exporter sugar installation) — ~2–3 days.
   - Phase B / D moved to "deferred / last resort" status with
     explicit re-trigger conditions.

3. Refreshes the open work items list with phase-tagged TODOs.

No code changes, just doc.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock
Copy link
Copy Markdown
Owner Author

fglock commented Apr 27, 2026

Superseded by #572, which includes both commits (Phase A + C-mini and Phase 2 stubs) plus the Phase-3+ planning update.

@fglock fglock closed this Apr 27, 2026
fglock added a commit that referenced this pull request Apr 27, 2026
After two iterative shim-widening PRs (#570, #572), the original
phase plan ("ship Quick path, then do A→B→D") needs revision. The
shim approach has paid out much faster than a full pure-Perl port
would have, so the doc now:

1. Records concrete lessons learned (compile-time stubs are
   high-leverage; pre-loading matters as much as having stubs;
   BAIL_OUT is a hidden multiplier; the gap is method surface, not
   metaclass semantics; stubs need correct @isa).

2. Replaces the stale "Decision needed" section with a concrete,
   data-driven Phase 3+ plan, sized against the actual remaining
   failure counts in the latest run:

   - Phase 3 (rich Moose::_FakeMeta + next batch of stubs +
     TypeConstraint isa fix) — ~1 day; expected payoff +15–25 green
     files / +200–500 newly passing assertions.
   - Phase 4 (hook into Moo's attribute store from FakeMeta) — ~2
     days; gives Test::Moose::has_attribute_ok real semantics.
   - Phase 5 (Moose::Util::MetaRole::apply_metaroles) — ~1 day.
   - Phase 6 (full Moose::Exporter sugar installation) — ~2–3 days.
   - Phase B / D moved to "deferred / last resort" status with
     explicit re-trigger conditions.

3. Refreshes the open work items list with phase-tagged TODOs.

No code changes, just doc.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
fglock added a commit that referenced this pull request Apr 28, 2026
After two iterative shim-widening PRs (#570, #572), the original
phase plan ("ship Quick path, then do A→B→D") needs revision. The
shim approach has paid out much faster than a full pure-Perl port
would have, so the doc now:

1. Records concrete lessons learned (compile-time stubs are
   high-leverage; pre-loading matters as much as having stubs;
   BAIL_OUT is a hidden multiplier; the gap is method surface, not
   metaclass semantics; stubs need correct @isa).

2. Replaces the stale "Decision needed" section with a concrete,
   data-driven Phase 3+ plan, sized against the actual remaining
   failure counts in the latest run:

   - Phase 3 (rich Moose::_FakeMeta + next batch of stubs +
     TypeConstraint isa fix) — ~1 day; expected payoff +15–25 green
     files / +200–500 newly passing assertions.
   - Phase 4 (hook into Moo's attribute store from FakeMeta) — ~2
     days; gives Test::Moose::has_attribute_ok real semantics.
   - Phase 5 (Moose::Util::MetaRole::apply_metaroles) — ~1 day.
   - Phase 6 (full Moose::Exporter sugar installation) — ~2–3 days.
   - Phase B / D moved to "deferred / last resort" status with
     explicit re-trigger conditions.

3. Refreshes the open work items list with phase-tagged TODOs.

No code changes, just doc.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant