Fix local package variable bug - our variables now see local changes#333
Merged
Conversation
Added notes about an attempted approach (skipping our variables from closure capture) that partially worked but broke Test::More due to constructor signature mismatches. Documented that the fix needs to happen at the variable access level, not closure capture level. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
- Added test cases in local.t (in __END__ section) for cross-package
our/local scenarios that currently fail
- Updated design doc with detailed findings from implementation attempts:
- Approach 1 (skip our from closures) broke constructor signatures
- Approach 2 (non-lexical our) breaks Test::More/Test2 due to
BEGIN block interactions
- The fix requires further investigation into how BEGIN blocks
interact with lexical closure capture
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <noreply@cognition.ai>
This fixes the bug where subroutines don't see 'local'ized values of 'our' variables set from outside their package. Root cause: 'our' variables were treated as lexical (stored in JVM local variable slots), capturing values at subroutine definition time. This meant 'local $Pkg::Var' changes weren't visible inside subroutines. The fix: 1. EmitVariable.java: Distinguish between BEGIN-captured 'our' variables (in PerlOnJava::_BEGIN_* packages, which should remain lexical for compile-to-runtime persistence) and regular 'our' variables (which should look up from GlobalVariable at runtime). 2. EmitSubroutine.java and SubroutineParser.java: Use 4-argument addVariable() to preserve the original perlPackage when copying variables to subroutine scopes. 3. ScopedSymbolTable.java: Add 4-argument addVariable() overload to allow explicit package specification. Test results: - All existing tests pass - New cross-package our/local tests pass (54 tests in local.t) - Test::More/Test2 modules work correctly - BEGIN block lexical persistence works correctly See dev/design/local-package-variable-fix.md for detailed analysis. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
…pilation error In Perl, calling exit() inside a BEGIN block terminates the program immediately. Previously, jperl would catch the PerlExitException and convert it to a "BEGIN failed--compilation aborted" error, then continue parsing and fail. This fix re-throws PerlExitException so it propagates to Main.main() which converts it to System.exit(). Fixes tests that use `plan skip_all` in BEGIN blocks (e.g., Log4perl's t/056SyncApp2.t and t/066SQLite.t) - they now skip cleanly without errors. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
…updates - Document PR #331 fix for exit() inside BEGIN blocks - Update test results (now 700 tests, 26 failures) - Mark 'local' package variable bug as verified fixed - Update t/020Easy.t issue category Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <noreply@cognition.ai>
fcc0d5e to
fd6bb95
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
This fixes the bug where subroutines don't see
localized values ofourvariables set from outside their package.Problem
This affected:
$Carp::CarpLevel(error reporting in all modules using Carp)local $Module::VariablepatternRoot Cause
ourvariables were treated as lexical (stored in JVM local variable slots), capturing values at subroutine definition time. Whenlocalreplaced the scalar in the symbol table, the subroutine's cached register still held the old reference.The Fix
EmitVariable.java: Distinguish between:
ourvariables (inPerlOnJava::_BEGIN_*packages) → remain lexical for compile-to-runtime persistenceourvariables → look up from GlobalVariable at runtimeEmitSubroutine.java and SubroutineParser.java: Preserve original
perlPackagewhen copying variables to subroutine scopesScopedSymbolTable.java: Add 4-argument
addVariable()overload for explicit package specificationTest Results
our/localtests pass (54 tests in local.t)Test plan
makepasses all unit testslocal.tincludes new cross-package testsuse Test::Moreworks correctlyGenerated with Devin