Issue Details (XML | Word | Printable)

Key: JRUBY-2605
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Charles Oliver Nutter
Reporter: Vladimir Sizikov
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
JRuby

Kernel.eval with yield behaves differently than MRI 1.8.6/1.8.7, causes some libraries failures with JRuby

Created: 02/Jun/08 12:44 PM   Updated: 30/Nov/08 10:52 PM   Resolved: 04/Jun/08 10:54 AM
Component/s: Core Classes/Modules
Affects Version/s: JRuby 1.1.2
Fix Version/s: JRuby 1.1.3

Time Tracking:
Not Specified

File Attachments: 1. File eval-specs.rb (0.9 kB)

Environment: Latest JRuby 1.1.2
Issue Links:
Related
 


 Description  « Hide

Kernel.eval in JRuby have the following issues that actually cause some libraries (like Sinatra) to fail with JRuby:

1. ruby -ve "p eval('yield') { 'vvs' }"
ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]
"vvs"

jruby -ve "p eval('yield') { 'vvs' }"
ruby 1.8.6 (2008-06-02 rev 6586) [i386-jruby1.1.2]
: yield called out of block (LocalJumpError)

2.

def render
  eval("yield", binding)
end
p render { "vvs" }

Again, JRuby raises LocalJumpError here.

I'm attaching the specs file (to be integrated into RubySpecs).

Here's the output:

mspec -f s -t /opt/ruby1.8-stable/bin/ruby eval-render.rb

Kernel.eval
- yields to the provided block when evaling 'yield'
- does not yield to the provided block when evaling 'yield' when scope argument is present
- yields to the block captured by binding
- does not pass the block to the method being eval'ed


Finished in 0.002724 seconds

>mspec -f s -t j eval-render.rb

Kernel.eval
- yields to the provided block when evaling 'yield' (ERROR - 1)
- does not yield to the provided block when evaling 'yield' when scope argument is present
- yields to the block captured by binding (ERROR - 2)
- does not pass the block to the method being eval'ed


1)
Kernel.eval yields to the provided block when evaling 'yield' ERROR
LocalJumpError: yield called out of block


2)
Kernel.eval yields to the block captured by binding ERROR
LocalJumpError: yield called out of block


See also JRUBY-2599 for the example where this problem is visible.



Charles Oliver Nutter added a comment - 04/Jun/08 10:54 AM

I've fixed the issue with eval 'yield', binding in r6886. The other failures, where a block is passed directly to yield, have been confirmed as unintentional behavior in Ruby 1.8, so we're not going to fix them. And they seem really wrong anyway.


Emmanuel Pirsch added a comment - 07/Nov/08 11:51 AM

I guess this should be reopened...

With JRuby 1.1.4...

C:\>jruby -v
jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-08-28 rev 7570) [x86-java]

I get :

C:\>jruby -ve "p eval('yield')

Unknown macro: { 'vvs' }
"
jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-08-28 rev 7570) [x86-java]
org.jruby.runtime.ThreadContext:628:in `addBackTraceElement': java.lang.NullPointerException
from org.jruby.runtime.ThreadContext:738:in `createBacktraceFromFrames'
from org.jruby.runtime.ThreadContext:697:in `createBacktraceFromFrames'
from org.jruby.RubyException:180:in `initBacktrace'
from org.jruby.RubyException:166:in `getBacktrace'
from org.jruby.RubyException:199:in `backtrace'
from org.jruby.RubyException$i_method_0_0$RUBYINVOKER$backtrace:-1:in `call'
from org.jruby.RubyClass:418:in `finvoke'
from org.jruby.javasupport.util.RuntimeHelpers:339:in `invoke'
from org.jruby.RubyObject:692:in `callMethod'
from org.jruby.Ruby:2026:in `printError'
from org.jruby.Main:235:in `run'
from org.jruby.Main:100:in `run'
from org.jruby.Main:84:in `main'

C:\>jruby -ve "p eval('yield', binding)

Unknown macro: { 'vvs' }
"
jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-08-28 rev 7570) [x86-java]
null:1:in `binding': yield called out of block (LocalJumpError)
from -e:1:in `eval'
from -e:1

C:\>jirb
irb(main):001:0> def render
irb(main):002:1> eval("yield", binding)
irb(main):003:1> end
=> nil
irb(main):004:0> p render

Unknown macro: { "vvs" }

LocalJumpError: yield called out of block
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-token.rb:54:in `binding'
from (irb):3:in `eval'
from (irb):3:in `render'
from (irb):5:in `binding'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/workspace.rb:53:in `eval'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/workspace.rb:81:in `evaluate'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/context.rb:219:in `evaluate'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:150:in `eval_input'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:259:in `signal_status'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:147:in `eval_input'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:146:in `eval_input'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:70:in `start'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:69:in `catch'
from C:/apps/jruby-1.1.4/lib/ruby/1.8/irb.rb:69:in `start'
from c:\apps\jruby-1.1.4\bin\jirb:19Maybe IRB bug!!
irb(main):005:0>


Emmanuel Pirsch added a comment - 07/Nov/08 12:09 PM

And with jRuby 1.1.5 :

C:\apps\jruby-1.1.5\bin>.\jruby -ve "p eval('yield') { 'vvs' }"
jruby 1.1.5 (ruby 1.8.6 patchlevel 114) (2008-11-03 rev 7996) [x86-java]
org.jruby.runtime.ThreadContext:638:in `addBackTraceElement': java.lang.NullPointerException
        from org.jruby.runtime.ThreadContext:748:in `createBacktraceFromFrames'
        from org.jruby.runtime.ThreadContext:707:in `createBacktraceFromFrames'
        from org.jruby.RubyException:178:in `initBacktrace'
        from org.jruby.RubyException:164:in `getBacktrace'
        from org.jruby.RubyException:197:in `backtrace'
        from org.jruby.RubyException$i_method_0_0$RUBYINVOKER$backtrace:-1:in `call'
        from org.jruby.RubyClass:428:in `finvoke'
        from org.jruby.javasupport.util.RuntimeHelpers:302:in `invoke'
        from org.jruby.RubyObject:689:in `callMethod'
        from org.jruby.Ruby:2040:in `printError'
        from org.jruby.Main:235:in `run'
        from org.jruby.Main:100:in `run'
        from org.jruby.Main:84:in `main'

Charles Oliver Nutter added a comment - 30/Nov/08 10:52 PM

Emmanuel: The behavior you demonstrate is exactly the behavior that ruby-core has deemed "unspecified". It's a side effect of the way 1.8 is designed, and should not be expected to work under 1.9 or JRuby.