Skip to content

JRuby 9.1.*.* on multiple platforms incorrectly handles block in [] method calls #4217

@ab

Description

@ab

JRuby starting with 9.1.0.0 and affecting all 9.1.x.x versions appears to incorrectly handle blocks passed as procs to the special [] method.

In MRI ruby 2.x and in jruby 9.0.5.0, foo[i, &block] works as expected.
In jruby 9.1.x.x, the block is not passed through and the method receives nil instead.

Versions tested

Tested jruby versions on OS X:

  • jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.0.0 (2.3.0) 2016-05-02 a633c63 Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.1.0 (2.3.0) 2016-05-19 fe84e89 Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.2.0 (2.3.0) 2016-05-26 7357c8f Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.3.0 (2.3.1) 2016-08-29 a2a3b29 Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.4.0 (2.3.1) 2016-09-01 2e1327f Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
  • jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]

Tested jruby versions on linux:

  • jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d OpenJDK 64-Bit Server VM 25.91-b14 on 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14 +jit [linux-amd64]
  • jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 OpenJDK 64-Bit Server VM 25.91-b14 on 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14 +jit [linux-x86_64]

What is especially interesting is that calling the :[] method with send() passes the block through correctly.

Test script

#!/usr/bin/env ruby

class Foo
  attr_reader :failed

  def initialize
    @failed = false
  end

  def [](foo, &block)
    if block_given?
      puts "block_given, block: " + block.inspect
    else
      puts "NOT block_given, block: " + block.inspect
      @failed = true
    end
  end

  def test_method(foo, &block)
    if block_given?
      puts "block_given, block: " + block.inspect
    else
      puts "NOT block_given, block: " + block.inspect
      @failed = true
    end
  end
end


f = Foo.new

puts '--'
puts RUBY_DESCRIPTION

block = proc {|r| r}

puts
puts 'Test 1: f[&block]'
f['foo', &block]

puts
puts 'Test 2: test_method(&block)'
f.test_method('foo', &block)

puts
puts 'Test 3: f.[](&block)'
f.[]('foo', &block)

puts
puts 'Test 4: f.public_send(:[], &block)'
f.public_send(:[], 'foo', &block)

if f.failed
  puts 'FAILED'
  exit 1
else
  puts 'Succeeded'
end

Results

Sample output from successful MRI ruby 2.3.1

ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-linux]

Test 1: f[&block]
block_given, block: #<Proc:0x00556f28d89dd8@./test.rb:35>

Test 2: test_method(&block)
block_given, block: #<Proc:0x00556f28d89dd8@./test.rb:35>

Test 3: f.[](&block)
block_given, block: #<Proc:0x00556f28d89dd8@./test.rb:35>

Test 4: f.public_send(:[], &block)
block_given, block: #<Proc:0x00556f28d89dd8@./test.rb:35>
Succeeded

Sample output from successful jruby 9.0.5.0

jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d OpenJDK 64-Bit Server VM 25.91-b14 on 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14 +jit [linux-amd64]

Test 1: f[&block]
block_given, block: #<Proc:0x9629756@./test.rb:35>

Test 2: test_method(&block)
block_given, block: #<Proc:0x9629756@./test.rb:35>

Test 3: f.[](&block)
block_given, block: #<Proc:0x9629756@./test.rb:35>

Test 4: f.public_send(:[], &block)
block_given, block: #<Proc:0x9629756@./test.rb:35>
Succeeded

Sample output from failing jruby 9.1.5.0

jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 OpenJDK 64-Bit Server VM 25.91-b14 on 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14 +jit [linux-x86_64]

Test 1: f[&block]
NOT block_given, block: nil

Test 2: test_method(&block)
block_given, block: #<Proc:0x6e0e048a@./test.rb:35>

Test 3: f.[](&block)
NOT block_given, block: nil

Test 4: f.public_send(:[], &block)
block_given, block: #<Proc:0x6e0e048a@./test.rb:35>
FAILED

Versions 9.1.0.0, 9.1.1.0, 9.1.2.0, 9.1.3.0, 9.1.4.0, and 9.1.5.0 are all affected.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions