Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: JRuby 1.6.7
    • Fix Version/s: JRuby 2
    • Component/s: Ruby 1.9.3
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Found while updating test/rubicon/* for 1.9 mode. 1.9.3 passes this (test_blocks_procs.rb:97):

      IS19 = RUBY_VERSION =~ /1\.9/
      o = Object.new
      def o.f; yield *[[]]; end
      o.f {|a,b,*c| puts [a,b,c].inspect}
      
      # 1.9 => [nil, nil, []]
      # JRuby --1.9 => [[], nil, []]
      

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        A similar case from test/rubicon/test_loop_stuff.rb:254:

          class IterTest
            def initialize(e); @body = e; end
            
            def each0(&block); @body.each(&block); end
            def each1(&block); @body.each { |*x| block.call(*x) } end
            def each2(&block); @body.each { |*x| block.call(x) } end
            def each3(&block); @body.each { |x| block.call(*x) } end
            def each4(&block); @body.each { |x| block.call(x) } end
            def each5; @body.each { |*x| yield(*x) } end
            def each6; @body.each { |*x| yield(x) } end
            def each7; @body.each { |x| yield(*x) } end
            def each8; @body.each { |x| yield(x) } end
          end
        
        ...
            IterTest.new([[5]]).each5 { |x2| x = x2 }
            assert_equal([5], x)
        
        Show
        Charles Oliver Nutter added a comment - A similar case from test/rubicon/test_loop_stuff.rb:254: class IterTest def initialize(e); @body = e; end def each0(&block); @body.each(&block); end def each1(&block); @body.each { |*x| block.call(*x) } end def each2(&block); @body.each { |*x| block.call(x) } end def each3(&block); @body.each { |x| block.call(*x) } end def each4(&block); @body.each { |x| block.call(x) } end def each5; @body.each { |*x| yield(*x) } end def each6; @body.each { |*x| yield(x) } end def each7; @body.each { |x| yield(*x) } end def each8; @body.each { |x| yield(x) } end end ... IterTest.new([[5]]).each5 { |x2| x = x2 } assert_equal([5], x)
        Hide
        Charles Oliver Nutter added a comment -

        Likely related to JRUBY-6550.

        Show
        Charles Oliver Nutter added a comment - Likely related to JRUBY-6550 .
        Hide
        Charles Oliver Nutter added a comment -

        Still broken as of today on master (1.7.0pre2).

        Show
        Charles Oliver Nutter added a comment - Still broken as of today on master (1.7.0pre2).
        Hide
        Charles Oliver Nutter added a comment -

        I don't want to fix this. I think 1.9.3 and 2.0.0 are wrong.

        Filed a bug with MRI...we'll see what they say: https://bugs.ruby-lang.org/issues/6994

        Show
        Charles Oliver Nutter added a comment - I don't want to fix this. I think 1.9.3 and 2.0.0 are wrong. Filed a bug with MRI...we'll see what they say: https://bugs.ruby-lang.org/issues/6994
        Hide
        Charles Oliver Nutter added a comment -

        According to MRI folks, this is not a bug. I reluctantly agree with them, though I think the behavior is surprising.

        A block with arguments like |a, b| behaves the same way as a method like def foo((a, b)) where the extra () is spreading out a single incoming argument into multiple arguments for distribution to a, b. However, a single-argument block |a| does not do any spreading and behaves like a method def foo(a), i.e. normal 1:1 argument assignment.

        Given block arguments' roots in multiple assignment, and the behavior of 1.8 block arguments, this behavior is somewhat consistent if you ignore the inconsistency of spreading the incoming array only in multiple arguments' case.

        We will not be able to fix this for JRuby 1.7, because the block dispatch paths are still very much oriented toward 1.8 behavior. All attempts I have made to patch for this specific case have failed, because they either cause too many other cases to unwrap, or they cause the single arg case to spread the array. We need to be able to focus exclusively on 1.9 behavior throughout block dispatch to make this work right, which won't happen until JRuby 9k.

        Show
        Charles Oliver Nutter added a comment - According to MRI folks, this is not a bug. I reluctantly agree with them, though I think the behavior is surprising. A block with arguments like |a, b| behaves the same way as a method like def foo((a, b)) where the extra () is spreading out a single incoming argument into multiple arguments for distribution to a, b. However, a single-argument block |a| does not do any spreading and behaves like a method def foo(a), i.e. normal 1:1 argument assignment. Given block arguments' roots in multiple assignment, and the behavior of 1.8 block arguments, this behavior is somewhat consistent if you ignore the inconsistency of spreading the incoming array only in multiple arguments' case. We will not be able to fix this for JRuby 1.7, because the block dispatch paths are still very much oriented toward 1.8 behavior. All attempts I have made to patch for this specific case have failed, because they either cause too many other cases to unwrap, or they cause the single arg case to spread the array. We need to be able to focus exclusively on 1.9 behavior throughout block dispatch to make this work right, which won't happen until JRuby 9k.
        Hide
        Charles Oliver Nutter added a comment -

        The additional case in test_loop_stuff now works, and has been unmasked in r59781a8. The original *[[]] case still fails.

        Show
        Charles Oliver Nutter added a comment - The additional case in test_loop_stuff now works, and has been unmasked in r59781a8. The original *[[]] case still fails.

          People

          • Assignee:
            Thomas E Enebo
            Reporter:
            Charles Oliver Nutter
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: