Skip to content

Dynamic Moose constructors pass string \\@ instead of HashRef #1393

Closed

Description

@fglock

Summary

Spreadsheet::Reader::Format v0.6.5 fails on PerlOnJava when its tests use
MooseX::ShortCut::BuildInstance to dynamically construct classes with roles
and typed attributes. PerlOnJava passes the literal string "\\@" to a
HashRef attribute instead of the expected hash reference.

The failure reproduces on both the JVM backend and the interpreter backend.

CPAN evidence

  • Distribution: Spreadsheet-Reader-Format v0.6.5
  • CPAN run: 20260915-125610-17469
  • Failure record: FAIL Spreadsheet::Reader::Format Spreadsheet::Reader::Format
  • Upstream test suite: 4 test files, 1,411 tests
  • System Perl result: all 1,411 tests pass
  • PerlOnJava result: 3 of 4 test files fail after the test command starts
  • Target distribution: pure Perl; no XS or native-library prerequisite

The archived CPAN run reached the target test command but exceeded the
tester’s 120-second soft limit without producing output. A bounded direct run
completed after approximately 163 seconds and produced the deterministic
failures below, so this is not classified as a timeout-only failure.

Observed failure

The first failing test reports:

Attribute (defined_excel_translations) does not pass the type constraint:
Value "\\@" did not pass type constraint "HashRef"

The error originates while MooseX::ShortCut::BuildInstance constructs a
temporary class and applies the Spreadsheet::Reader::Format roles. The
subsequent test-harness error is:

Can't call method "find_attribute_by_name" on an undefined value

The same defined_excel_translations/"\\@" failure occurs in:

  • t/Spreadsheet/Reader/01-format_interface.t
  • t/Spreadsheet/Reader/Format/02-fmt_default.t
  • t/Spreadsheet/Reader/Format/03-parse_excel_fmt_string.t

t/Spreadsheet/Reader/Format/01-types.t passes.

Minimal reproducer shape

The upstream tests call build_instance with dynamically selected
superclasses and roles, for example:

my $test_instance = build_instance(
    package => 'FormatInterfaceTest',
    superclasses => [ 'Spreadsheet::Reader::Format::FmtDefault' ],
    add_roles_in_sequence => [
        'Spreadsheet::Reader::Format::ParseExcelFormatStrings',
        'Spreadsheet::Reader::Format',
    ],
    _alt_epoch_year => 1904,
);

The generated class contains a defined_excel_translations attribute typed
as HashRef. Under standard Perl, construction succeeds. Under PerlOnJava,
the constructor receives "\\@" for that attribute and rejects it before the
test assertions can run.

Backend scope

The failure is reproducible on both backends:

  • JVM backend: the three tests fail with the typed-attribute error.
  • Interpreter backend: the same typed-attribute error appears in the first
    two failing tests before the bounded run ends.

This makes a backend-specific implementation defect unlikely; the shared
dynamic-evaluation, argument construction, Moose integration, or reference
representation path is the likely ownership area.

Impact

This blocks a pure-Perl spreadsheet formatting module and hides 1,390 of the
1,411 upstream assertions behind constructor failures. More broadly, the
same defect may affect CPAN modules that use Moose roles, dynamically
generated classes, typed attributes, and MooseX::ShortCut::BuildInstance.
Applications may see constructor failures or invalid typed values rather than
the expected object instances.

Expected fix

Preserve Perl-compatible reference values and constructor arguments when
dynamic classes are generated and instantiated through eval-constructed
code. In particular, a HashRef attribute must receive an actual hash
reference, not the string "\\@".

Add permanent project-owned regression coverage, validated first with system
Perl, covering:

  1. A dynamically generated Moose class with a HashRef attribute.
  2. Role application through add_roles_in_sequence.
  3. Constructor invocation through MooseX::ShortCut::BuildInstance.
  4. JVM/interpreter parity.

Deduplication

Existing issues were searched using the distribution name, stable error text,
MooseX::ShortCut::BuildInstance, defined_excel_translations, and the
HashRef/reference symptom.

This report is therefore not a duplicate.

Activity

  1. added
    bugSomething isn't working
    area:runtimeCore Perl runtime semantics
    area:cpan-portCPAN compatibility ports and providers
    area:backendJVM interpreter or execution-backend behavior
    on Sep 16, 2026
  2. fglock commented on Oct 19, 2026

    @fglock
    OwnerAuthor

    Follow-up after PR #1849: this issue is not fully fixed by that PR. The change adds a project-owned dynamic Moose HashRef/role constructor regression, but does not modify the constructor path because the exact Spreadsheet-Reader-Format v0.6.5 interface test passed on the then-current parent build during investigation. That means the original reported failure was not reproduced in that validation run; this PR should not be treated as resolving it. The issue remains open for a deterministic reproduction and a targeted runtime fix, including MooseX::ShortCut::BuildInstance coverage on both backends.

  3. fglock commented on Oct 23, 2026

    @fglock
    OwnerAuthor

    Resolved by merged PR #1872. The dynamic Moose BuildInstance HashRef regression passes on system Perl and both PerlOnJava backends, and Spreadsheet-Reader-Format 0.6.5 passes all 4 upstream files and 1,411 tests on both backends. Closing as completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:backendJVM interpreter or execution-backend behaviorarea:cpan-portCPAN compatibility ports and providersarea:runtimeCore Perl runtime semanticsbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions