fix(naming): honor local *PKG::__ANON__ = 'name' in caller()/Sub::Util#617
Merged
fix(naming): honor local *PKG::__ANON__ = 'name' in caller()/Sub::Util#617
Conversation
Anonymous subs now expose the dynamically-scoped name set by the `local *__ANON__ = 'name'` idiom (used by SUPER.pm, Try::Tiny, namespace::clean, several Moose internals) to caller() and Sub::Util::subname. Mechanism (see dev/modules/anon_sub_naming.md): * RuntimeGlob gains a `nameOverride` string. Glob-as-scalar assignment (`*foo = $string`) records it on the *current* glob in globalIORefs (looked up by name via the new GlobalVariable.peekGlobalIO helper), so the override follows the fresh glob installed by `local *FOO` rather than the lvalue captured before `local`. * RuntimeCode.callerWithSub consults globalIORefs["Pkg::__ANON__"].nameOverride for any anon-sub frame (innermost via __SUB__, deeper via the stack-trace "Pkg::__ANON__" record). Sub::Name / set_subname's explicitlyRenamed path keeps winning, so already-renamed CVs are unaffected. * SubUtil.subname uses the same lookup. Unblocks the SUPER → Test::MockModule → DBIx::Retry chain: * SUPER t/bugs.t: 0/6 → 6/6. * Test::MockModule installs cleanly, 103/103 tests pass. * DBIx::Retry was bailing out at "Test::MockModule not found" (0 subtests run); now runs 17/17 subtests, with one remaining unrelated DBD::ExampleP failure. * Sub::Name baseline behavior is byte-identical to before (regression baseline captured in dev/modules/anon_sub_naming_baseline.txt). * `make` passes. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
58d865d to
c3effde
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make
caller()andSub::Util::subnamehonor thelocal *PKG::__ANON__ = 'name'idiom for naming anonymous subs.This is used by SUPER.pm, Try::Tiny, namespace::clean, and several
Moose internals so that stack traces and SUPER-dispatch report a
meaningful name for anon subs.
Previously the idiom was silently lost and
caller(0)[3]alwaysreturned
Pkg::__ANON__, which brokeSUPER'st/bugs.t(3/6failures) and consequently
Test::MockModule(which couldn'tinstall) and any module that depends on it (e.g.
DBIx::Retry).Mechanism (see
dev/modules/anon_sub_naming.md)RuntimeGlobgains anameOverridestring. Glob-as-scalarassignment (
*foo = $string) records the override on thecurrent glob in
globalIORefs(looked up by name via a newnon-vivifying
GlobalVariable.peekGlobalIOhelper), so theoverride correctly follows the fresh
RuntimeGlobthatlocal *FOOswaps in, not the lvalue captured beforelocal.RuntimeCode.callerWithSubconsultsglobalIORefs["Pkg::__ANON__"].nameOverridefor any anon-subframe (innermost via
__SUB__, deeper frames via the stack-tracePkg::__ANON__marker).Sub::Name/set_subname'sexplicitlyRenamedpath keeps winning, so a CV that wasrenamed via
Sub::Nameis unaffected by an outerlocal *__ANON__,matching real Perl.
SubUtil.subnameuses the same lookup.This is option A from the design discussion in
dev/modules/anon_sub_naming.md("glob indirection"), implementedin a narrow, low-risk form that does not change the SCALAR-slot
semantics of
*foo = "string"for any other use case.Test plan
makepasses (full unit-test suite + build)t/bugs.t: 0/6 → 6/6 passingTest::MockModuleinstalls cleanly; 103/103 tests passDBIx::Retrychain unblocked: was bailing out at"Test::MockModule not found" (0 subtests run); now runs
17/17 subtests (one remaining failure is an unrelated
DBD::ExampleP issue)
Sub::Nameregression baseline diff is empty(
dev/modules/anon_sub_naming_baseline.txtcaptured beforethe change)
plain anon, override, post-
localreset,Sub::Name+localinteraction,
Sub::Util::subnameinsidelocal,package-qualified, nested anon frames,
caller(N)fromhelpers, multi-call independence
Files
src/main/java/org/perlonjava/runtime/runtimetypes/RuntimeGlob.java—
nameOverridefield, write pathsrc/main/java/org/perlonjava/runtime/runtimetypes/GlobalVariable.java—
peekGlobalIOhelpersrc/main/java/org/perlonjava/runtime/runtimetypes/RuntimeCode.java—
callerWithSubread pathsrc/main/java/org/perlonjava/runtime/perlmodule/SubUtil.java—
subnameread pathdev/modules/anon_sub_naming.md— design docdev/modules/anon_sub_naming_baseline.txt— captured Sub::Namebaseline (no diff after this change)
Generated with Devin