Skip to content

Data.define single-attribute class rejects positional arguments #9214

@rossroberts-toast

Description

@rossroberts-toast

Environment Information

  • JRuby version: jruby 10.0.2.0 (3.4.2) 2025-08-07 cba6031bd0 OpenJDK 64-Bit Server VM 21.0.10+7-LTS on 21.0.10+7-LTS +indy +jit [arm64-darwin]
  • Operating system: macOS (Darwin 25.2.0, arm64-darwin)
  • Java version: OpenJDK 21.0.10 (Corretto-21.0.10.7.1)

Expected Behavior

When a method uses both *args and **kwargs parameters and calls another method with both splat operators, the arguments should be properly unpacked and passed through - matching MRI Ruby 3.4.4 behavior.

Actual Behavior

given jruby_bug.rb:

#!/usr/bin/env ruby

puts "Ruby: #{RUBY_DESCRIPTION}\n"

# Test 1: Splat forwarding works fine with regular methods
def regular_method(arg)
  arg
end

def test_splat_forwarding(*args, **kwargs)
  regular_method(*args, **kwargs)
end

puts "✓ Test 1 - Splat forwarding to regular method: #{test_splat_forwarding("works")}"

# Test 2: Data.define works fine without splat forwarding
MyData = Data.define(:value)

def test_data_no_splat(arg)
  MyData.new(arg)
end

puts "✓ Test 2 - Data.define without splat forwarding: #{test_data_no_splat("works").value}"

# Test 3: FAILS - Data.define with BOTH *args and **kwargs
def test_data_with_both_splats(*args, **kwargs)
  MyData.new(*args, **kwargs)
end

begin
  puts "✓ Test 3 - Data.define with both splats: #{test_data_with_both_splats("fails").value}"
rescue ArgumentError => e
  puts "✗ Test 3 - Data.define with both splats: #{e.class}: #{e.message}"
end

# Test 4: Works with only *args (no **kwargs)
def test_data_with_only_args(*args)
  MyData.new(*args)
end

puts "✓ Test 4 - Data.define with only *args: #{test_data_with_only_args("works").value}"

with MRI 3.4.4:

Ruby: ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [arm64-darwin24]
✓ Test 1 - Splat forwarding to regular method: works
✓ Test 2 - Data.define without splat forwarding: works
✓ Test 3 - Data.define with both splats: fails
✓ Test 4 - Data.define with only *args: works

with JRuby 10.0.2.0:

Ruby: jruby 10.0.2.0 (3.4.2) 2025-08-07 cba6031bd0 OpenJDK 64-Bit Server VM 21.0.10+7-LTS on 21.0.10+7-LTS +indy +jit [arm64-darwin]
✓ Test 1 - Splat forwarding to regular method: works
✓ Test 2 - Data.define without splat forwarding: works
✗ Test 3 - Data.define with both splats: ArgumentError: wrong number of arguments (given 1, expected 0)
✓ Test 4 - Data.define with only *args: works

Summary

The error occurs specifically when:

  1. A method has BOTH *args AND **kwargs parameters (even when kwargs is empty)
  2. That method calls a Data.define (or Struct) constructor with new(*args, **kwargs)

Important notes:

  • Splat forwarding works fine with regular methods (Test 1)
  • Data.define works fine without splat forwarding (Test 2)
  • Data.define works fine with only *args (Test 4)
  • Only the combination of both splats + Data.define/Struct fails (Test 3)
  • Struct.new has the same issue although it causes ClassCastException instead of ArgumentError

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions