2016-12-22 5 views
4

(그들은 동일하지만 결과는 다릅니다) 다음과 같은 시나리오를 비교 :루비와 jruby에서 begin-next-end의 동작이 다른 이유는 무엇입니까?

먼저 내가 루비에 그것을 할 수 있습니다 JRuby를에 (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 

지금 같은 일 :

~> 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 

크루비 에서처럼 jruby에서 왜 실패하지 않습니까? 이것은 jruby 버그입니까?

+3

또 다른 가능성은 IRb의 구현 아티팩트 일 수 있습니다.IRb의 구현은 hackish하고 깨지기 쉽고 (관대하기 때문에) 잘 알려져 있으며 그 행동은 스크립트와 동일한 코드 실행의 동작과 반드시 ​​일치하지 않습니다. 좀 더 잘 알려진 비 호환성의 일부는 최상위 메소드가 사적이어야하고 지역 변수 주위의 이상 함에도 불구하고 공개된다는 것입니다. 그러나 제어 흐름에 대한 몇 가지 차이점이 있다는 것이 의문의 여지가 없습니다. 특히, 당신의 에러 메시지는 당신이 사용하지 않는'eval'에 대해 언급합니다 ... –

+2

... 당신의 코드보다는 IRb 자체의 구현에서 에러가 발생한다는 강한 암시가있는 것 같습니다. –

+0

입력 해 주셔서 감사합니다! Ruby :'Invalid next (SyntaxError)'와 jruby :'LocalJumpError : unexpected next' – Kalsan

답변

1

나는 이것을 Bug #13064으로 제출했다.

  • YARV 2.2.0 (빌드가 맥 OS와 함께 배송)

    :

    나는 JRuby를, MRuby 및 Rubinius의 최신 버전뿐만 아니라 YARV 버전의 다양한 코드를 테스트
    # 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에서와 호환 주장 버전)

    # 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 
    
  • 012,327,

    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 (어제 일 현재 SVN 트렁크) :

    # 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 
    
  • 루비니우스 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 (10)은 (최신 버전)

    # 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 (최소 ISO 규격 루비 구현이 자신을 마츠에 의해 작성)

    # 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

MRI는 Ruby 1.9 시간대를 중심으로 LocalJumpError를 발생시키기보다는 이러한 불법 점프 사례를 구문 분석 할 때 감지하기 시작했습니다. JRuby, MRuby 및 Rubinius는 여전히 점프를 그대로 유지하고 Syntax 오류를 즉시 제기하는 대신 호출 될 때 실패하게 만듭니다.

JRuby에서 버그를 제출할 가치가 있습니다. 파서는 기본적으로 MRI의 포트이므로 동일한 오류를 발생시킬 수 있어야합니다. 컴파일 시간에이 분석을 수행하고 오류를 제기 할 수 있습니다.