Why is the begin-next-end behavior different in ruby ​​and jruby?

Compare the following scenarios (they are the same, but the result is different):

First I'll do it on a ruby ​​(cruby)

~> irb
irb(main):001:0> begin
irb(main):002:1* begin
irb(main):003:2* puts 1
irb(main):004:2> next
irb(main):005:2> end
irb(main):006:1> puts 2
irb(main):007:1> end
SyntaxError: (irb):4: Can't escape from eval with next

Now the same on jruby:

~> jirb
irb(main):001:0> begin
irb(main):002:1* begin
irb(main):003:2* puts 1
irb(main):004:2> next
irb(main):005:2> end
irb(main):006:1> puts 2
irb(main):007:1> end
1
=> nil

Why does this not happen on jruby, how does this happen on cruby? Is this a jruby bug?

+4
source share
2 answers

I filed this as Error No. 13064 .

I tested your code in many versions of YARV, as well as in the latest versions of JRuby, MRuby, and Rubinius:

  • YARV 2.2.0 (sending assembly using macOS)

    # ruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]
    -e:1: warning: statement not reached
    -e:1: Invalid next
    -e: compile error (SyntaxError)
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.0.0"
    => "2.0.0"
    irb(main):002:0> p RUBY_ENGINE
    "ruby"
    => "ruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    (irb):9: warning: statement not reached
    Exception `SyntaxError' at /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/irb/workspace.rb:86 - (irb):7: Can't escape from eval with next
    Exception `SyntaxError' at /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/irb/workspace.rb:86 - (irb):7: Can't escape from eval with next
    SyntaxError: (irb):7: Can't escape from eval with next
        from (irb)
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • YARV 2.3.1 (JRuby version claims to be compatible at the moment)

    # ruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
    -e:1: warning: statement not reached
    -e: -e:1: Invalid next (SyntaxError)
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.3.1"
    => "2.3.1"
    irb(main):002:0> p RUBY_ENGINE
    "ruby"
    => "ruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    (irb):9: warning: statement not reached
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    SyntaxError: (irb):7: Can't escape from eval with next
        from (irb)
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • YARV 2.3.3

    # ruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]
    -e:1: warning: statement not reached
    -e: -e:1: Invalid next (SyntaxError)
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.3.3"
    => "2.3.3"
    irb(main):002:0> p RUBY_ENGINE
    "ruby"
    => "ruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    (irb):9: warning: statement not reached
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.3/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.3/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.3.3/lib/ruby/2.3.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    SyntaxError: (irb):7: Can't escape from eval with next
        from (irb)
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • YARV 2.4.0-preview3:

    # ruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    ruby 2.4.0preview3 (2016-11-07 trunk 56661) [x86_64-darwin16]
    -e:1: warning: statement not reached
    -e: -e:1: Invalid next (SyntaxError)
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.4.0"
    => "2.4.0"
    irb(main):002:0> p RUBY_ENGINE
    "ruby"
    => "ruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    (irb):9: warning: statement not reached
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.4.0-preview3/lib/ruby/2.4.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    SyntaxError: (irb):7: Can't escape from eval with next
        from (irb)
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • YARV 2.4.0-dev (current SVN channel as of yesterday):

    # ruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    ruby 2.4.0dev (2016-12-22 trunk 57151) [x86_64-darwin16]
    -e:1: warning: statement not reached
    -e: -e:1: Invalid next (SyntaxError)
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.4.0"
    => "2.4.0"
    irb(main):002:0> p RUBY_ENGINE
    "ruby"
    => "ruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    (irb):9: warning: statement not reached
    Exception `SyntaxError' at /Users/joerg/.rbenv/versions/2.4.0-dev/lib/ruby/2.4.0/irb/workspace.rb:87 - (irb):7: Can't escape from eval with next
    SyntaxError: (irb):7: Can't escape from eval with next
        from (irb)
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • Rubinius 3.69

    # rbx -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    rubinius 3.69 (2.3.1 a57071c6 2016-11-17 3.8.1) [x86_64-darwin15.6.0]
    1
                    main # Rubinius::Loader at core/loader.rb:860
                   evals # Rubinius::Loader at core/loader.rb:646
                    eval # Kernel(Rubinius::Loader) at core/kernel.rb:1130
        call_on_instance # Rubinius::BlockEnvironment at core/block_environment.rb:147
       { } in __script__ # Object at -e:1
              jump_error . Rubinius at core/rubinius.rb:279
    
    invalid context for 'next' (LocalJumpError)
    
    An exception occurred evaluating command line code
    
    # irb
    irb(main):001:0> p RUBY_VERSION
    "2.3.1"
    => "2.3.1"
    irb(main):002:0> p RUBY_ENGINE
    "rbx"
    => "rbx"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    1
    LocalJumpError: invalid context for 'next'
        from core/rubinius.rb:279:in `jump_error'
        from (irb):7
        from core/block_environment.rb:147:in `call_on_instance'
        from core/kernel.rb:1130:in `eval'
        from core/kernel.rb:585:in `loop'
        from core/proc.rb:20:in `call'
        from core/kernel.rb:1067:in `catch'
        from core/throw_catch.rb:8:in `register'
        from core/kernel.rb:1066:in `catch'
        from core/proc.rb:20:in `call'
        from core/kernel.rb:1067:in `catch'
        from core/throw_catch.rb:8:in `register'
        from core/kernel.rb:1066:in `catch'
        from core/code_loader.rb:505:in `load_script'
        from core/code_loader.rb:590:in `load_script'
        from core/loader.rb:679:in `script'
        from core/loader.rb:861:in `main'irb(main):011:0> 
    irb(main):012:0* exit
    
  • JRuby 9.1.6.0 ( )

    # jruby -v -W -e 'begin; begin puts 1; next end; puts 2 end'
    jruby 9.1.6.0 (2.3.1) 2016-11-09 0150a76 Java HotSpot(TM) 64-Bit Server VM 25.102-b14 on 1.8.0_102-b14 +jit [darwin-x86_64]
    1
    LocalJumpError: unexpected next
      <main> at -e:1
    
    # irb -f -d -w -W
    irb(main):001:0> p RUBY_VERSION
    "2.3.1"
    => "2.3.1"
    irb(main):002:0> p RUBY_ENGINE
    "jruby"
    => "jruby"
    irb(main):003:0> 
    irb(main):004:0* begin
    irb(main):005:1*   begin
    irb(main):006:2*     puts 1
    irb(main):007:2>     next
    irb(main):008:2>   end
    irb(main):009:1>   puts 2
    irb(main):010:1> end
    1
    => nil
    irb(main):011:0> 
    irb(main):012:0* exit
    
  • MRuby 1.2.0 ( Ruby, ISO, matz)

    # mruby -v -e 'begin; begin puts 1; next end; puts 2 end'
    mruby 1.2.0 (2015-11-17) 
    00001 NODE_SCOPE:
    00001   NODE_BEGIN:
    00001     NODE_BEGIN:
    00001       NODE_BEGIN:
    00001         NODE_CALL:
    00001           NODE_SELF
    00001           method='puts' (383)
    00001           args:
    00001             NODE_INT 1 base 10
    00001         NODE_NEXT:
    00001       NODE_CALL:
    00001         NODE_SELF
    00001         method='puts' (383)
    00001         args:
    00001           NODE_INT 2 base 10
    irep 0x7fe0e3c1b630 nregs=4 nlocals=1 pools=1 syms=1 reps=0
    file: -e
        1 000 OP_LOADSELF   R1      
        1 001 OP_LOADI  R2  1   
        1 002 OP_SEND   R1  :puts   1
        1 003 OP_ERR    "unexpected next"
        1 004 OP_LOADSELF   R1      
        1 005 OP_LOADI  R2  2   
        1 006 OP_SEND   R1  :puts   1
        1 007 OP_STOP
    
    1
    trace:
        [0] -e:1
    LocalJumpError: unexpected next
    
    # irb -v
    mruby 1.2.0 (2015-11-17) 
    mirb - Embeddable Interactive Ruby Shell
    
    > p RUBY_VERSION
    00001 NODE_SCOPE:
    00001   NODE_BEGIN:
    00001     NODE_CALL:
    00001       NODE_SELF
    00001       method='p' (384)
    00001       args:
    00001         NODE_CONST RUBY_VERSION
    irep 0x7fceeac05220 nregs=4 nlocals=1 pools=0 syms=2 reps=0
    file: (mirb)
        1 000 OP_LOADSELF   R1      
        1 001 OP_GETCONST   R2  :RUBY_VERSION
        1 002 OP_SEND   R1  :p  1
        1 003 OP_STOP
    
    "1.9"
     => "1.9"
    > p RUBY_ENGINE
    00002 NODE_SCOPE:
    00002   NODE_BEGIN:
    00002     NODE_CALL:
    00002       NODE_SELF
    00002       method='p' (384)
    00002       args:
    00002         NODE_CONST RUBY_ENGINE
    irep 0x7fceeae05cf0 nregs=4 nlocals=1 pools=0 syms=2 reps=0
    file: (mirb)
        2 000 OP_LOADSELF   R1      
        2 001 OP_GETCONST   R2  :RUBY_ENGINE
        2 002 OP_SEND   R1  :p  1
        2 003 OP_STOP
    
    "mruby"
     => "mruby"
    > 
    00004 NODE_SCOPE:
    00004   NODE_BEGIN:
    irep 0x7fceeac06a50 nregs=2 nlocals=1 pools=0 syms=0 reps=0
    file: (mirb)
        4 000 OP_LOADNIL    R1      
        4 001 OP_STOP
    
     => nil
    > begin
    00005 NODE_NIL
    *   begin
    00007 NODE_NIL
    *     puts 1
    00009 NODE_NIL
    *     next
    00011 NODE_NIL
    *   end
    00013 NODE_NIL
    *   puts 2
    00015 NODE_NIL
    * end
    00012 NODE_SCOPE:
    00012   NODE_BEGIN:
    00012     NODE_BEGIN:
    00012       NODE_BEGIN:
    00012         NODE_CALL:
    00012           NODE_SELF
    00012           method='puts' (383)
    00012           args:
    00012             NODE_INT 1 base 10
    00013         NODE_NEXT:
    00015       NODE_CALL:
    00015         NODE_SELF
    00015         method='puts' (383)
    00015         args:
    00015           NODE_INT 2 base 10
    irep 0x7fceeae01130 nregs=4 nlocals=1 pools=1 syms=1 reps=0
    file: (mirb)
       12 000 OP_LOADSELF   R1      
       12 001 OP_LOADI  R2  1   
       12 002 OP_SEND   R1  :puts   1
       13 003 OP_ERR    "unexpected next"
       15 004 OP_LOADSELF   R1      
       15 005 OP_LOADI  R2  2   
       15 006 OP_SEND   R1  :puts   1
       15 007 OP_STOP
    
    1
    LocalJumpError: unexpected next
    > 
    00012 NODE_SCOPE:
    00012   NODE_BEGIN:
    irep 0x7fceeae078f0 nregs=2 nlocals=1 pools=0 syms=0 reps=0
    file: (mirb)
       12 000 OP_LOADNIL    R1      
       12 001 OP_STOP
    
     => nil
    > exit
    

, MRuby, JRuby Rubinius , YARV. YARV, . , .

+1

Ruby 1.9, , LocalJumpError. JRuby, MRuby Rubinius, , , , .

, JRuby. - , , , . , .

+1

Source: https://habr.com/ru/post/1664561/


All Articles