Skip to content

fix: enable jcpan -t Text::vCard and Directory::Scratch#585

Merged
fglock merged 1 commit intomasterfrom
fix/text-vcard-and-flock
Apr 28, 2026
Merged

fix: enable jcpan -t Text::vCard and Directory::Scratch#585
fglock merged 1 commit intomasterfrom
fix/text-vcard-and-flock

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 28, 2026

Summary

Investigation of jcpan -t Text::vCard (originally 16/18 test programs failing, 9/11 subtests failed) and the related Directory::Scratch test failures uncovered eight independent PerlOnJava bugs. This PR fixes all of them, taking both modules to a clean test pass and fixing several general-purpose IO/parser issues along the way.

Bundled-module fixes (Text::vCard prereqs)

  • MIME::QuotedPrint declares $VERSION and re-exports encode/decode aliases. Without $VERSION, use MIME::QuotedPrint 3.07 died with "does not define $MIME::QuotedPrint::VERSION".
  • File::Spec now sets @ISA = ("File::Spec::$platform") based on $^O instead of just (Exporter). Modules like Directory::Scratch and Path::Class derive the platform from $File::Spec::ISA[0]; without this they passed an empty string to _spec_class() and died with "Invalid system type ''".
  • New Unicode::LineBreak shim providing the minimal Unicode::GCString API (new/length/substr/as_string/columns) that Text::vCard::Node uses. Pure Perl, splits with \X for graphemes.

Interpreter & operator fixes

  • bless now emits the upstream "Use of uninitialized value $class in bless" and "Explicit blessing to '' (assuming package main)" warnings when given an undef class, matching real Perl. Tests like like $@, qr/Use of uninitialized value/ previously got an empty $@.
  • chmod $mode, @paths no longer silently no-ops. Operator.chmod was iterating runtimeList.elements directly, so an unflattened RuntimeArray slot stringified as ARRAY(0x...). Now flattens via addToList(...) like UnlinkOperator.
  • chomp / chop are now parsed as named-unary operators when used without parentheses. So is(chomp @a, 3, "ok") parses as is(chomp(@a), 3, "ok") — matching real Perl deparse output — instead of letting chomp gobble all of is()'s arguments.
  • Slurp-mode <$fh> on an empty file now returns the empty string on the first call and undef only on the second call. Previously it returned undef immediately, which broke Path::Tiny->slurp on empty files (and Directory::Scratch on top of that).
  • flock no longer leaks JVM-wide shared locks across abandoned Perl handles. Path::Tiny's slurp-then-append-with-truncate idiom used to fail with "Resource deadlock avoided" because the SHARED registry entry from the slurp's lexical $fh outlived the Perl scope. Added a Cleaner-based safety net plus a reactive reclaimAbandonedSharedLock retry path on EX-lock acquisition.

Test plan

  • make — full PerlOnJava unit-test suite passes.
  • ./jcpan -t Text::vCard — 18/18 test programs, 155/155 subtests pass.
  • ./jcpan -t Directory::Scratch (run via Test::Harness from blib) — 35/35 test programs, 691/691 subtests pass.

Files changed

src/main/java/org/perlonjava/runtime/operators/Operator.java
src/main/java/org/perlonjava/runtime/operators/Readline.java
src/main/java/org/perlonjava/runtime/operators/ReferenceOperators.java
src/main/java/org/perlonjava/runtime/io/CustomFileChannel.java
src/main/java/org/perlonjava/frontend/parser/CoreOperatorResolver.java
src/main/java/org/perlonjava/frontend/parser/OperatorParser.java
src/main/perl/lib/MIME/QuotedPrint.pm
src/main/perl/lib/File/Spec.pm
src/main/perl/lib/Unicode/LineBreak.pm   (new)
src/main/java/org/perlonjava/core/Configuration.java   (auto, gitCommitId)

Generated with Devin

Investigation of `jcpan -t Text::vCard` (16/18 test programs failing) and
the related Directory::Scratch test failures uncovered eight independent
PerlOnJava bugs.  Fixing them gets both modules to a clean test pass
(Text::vCard 155/155, Directory::Scratch 691/691) and fixes a number of
general-purpose IO/parser issues along the way.

Bundled-module fixes (Text::vCard prereqs)
- MIME::QuotedPrint declares `$VERSION` and re-exports `encode`/`decode`
  aliases, so `use MIME::QuotedPrint 3.07` and direct calls to
  `MIME::QuotedPrint::encode/decode` work.
- File::Spec now sets `@ISA = ("File::Spec::$platform")` per `$^O`
  instead of just `(Exporter)`.  Modules like Directory::Scratch and
  Path::Class derive the platform from `$File::Spec::ISA[0]`; without
  this they passed an empty string to `_spec_class()` and died with
  "Invalid system type ''".
- New `Unicode::LineBreak` shim providing the minimal `Unicode::GCString`
  API (new/length/substr/as_string/columns) that Text::vCard's Node.pm
  uses.  Implemented in pure Perl using `\X` for grapheme splitting.

Interpreter & operator fixes
- `bless` now emits the standard "Use of uninitialized value $class in
  bless" and "Explicit blessing to '' (assuming package main)" warnings
  when given an undef class, matching upstream Perl.  Tests like
  `like $@, qr/Use of uninitialized value/` previously got an empty $@.
- `chmod $mode, @paths` no longer silently no-ops.  `Operator.chmod`
  was iterating `runtimeList.elements` directly, so an unflattened
  RuntimeArray slot stringified as `ARRAY(0x...)`.  Now flattens via
  `addToList(...)` like `UnlinkOperator` does.
- `chomp` / `chop` are now parsed as named-unary operators when used
  without parentheses, so `is(chomp @A, 3, "ok")` parses as
  `is(chomp(@A), 3, "ok")` instead of letting chomp gobble all of
  is()'s arguments.  Matches Perl behaviour and the deparse output.
- Slurp-mode `<$fh>` (`local $/;`) on an empty file now returns the
  empty string on the first call and undef on the second call.
  Previously it returned undef immediately, which broke
  `Path::Tiny->slurp` on empty files (and Directory::Scratch built on
  top of that).
- `flock` no longer leaks JVM-wide shared locks across abandoned
  Perl handles.  Path::Tiny's slurp-then-append-with-truncate idiom
  used to fail with "Resource deadlock avoided" because the SHARED
  registry entry from the slurp's lexical $fh outlived the Perl scope.
  Added a `Cleaner`-based safety net plus a reactive
  `reclaimAbandonedSharedLock` retry path on EX-lock acquisition.

Verification
- `make` (PerlOnJava unit tests): all green.
- `./jcpan -t Text::vCard`: 18/18 test programs, 155/155 subtests.
- `./jcpan -t Directory::Scratch` (run from blib via Test::Harness):
  35/35 test programs, 691/691 subtests.

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the fix/text-vcard-and-flock branch from 4529d00 to 8616f15 Compare April 28, 2026 13:15
@fglock fglock merged commit 9198236 into master Apr 28, 2026
2 checks passed
@fglock fglock deleted the fix/text-vcard-and-flock branch April 28, 2026 13:32
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