Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble with instance_eval when using embedded API #4067

Open
chadselph opened this issue Aug 12, 2016 · 6 comments
Open

Trouble with instance_eval when using embedded API #4067

chadselph opened this issue Aug 12, 2016 · 6 comments

Comments

@chadselph
Copy link

chadselph commented Aug 12, 2016

First, I want to explain I am not a ruby programmer, so I probably haven't debugged this as well as I could have. I'm writing an application on the JVM that takes as its input some files from an existing ruby DSL. Basically, it makes use of instance_eval and the files it evals occasionally eval other files. I can't seem to get this to work from the embedded API.

Environment

Provide at least:

  • Version: org.jruby:jruby-complete:9.1.2.0
  • Operating system and platform: 14.5.0 Darwin Kernel Version 14.5.

Expected Behavior

I expect that running ::Kernel.eval from within a block of instance_eval will put the symbols in scope.

Actual Behavior

Code gets evaled, (confirmed with ::Kernel.puts) but symbols are not in scope.

I have a minimized example here, with the error and the behavior in standard ruby:

https://gist.github.com/chadselph/0be497f37b16f1b01009836686e3875c

Thanks for you time!

@chadselph
Copy link
Author

Just discovered this behaves as expected in JRuby 1.7.25, but not 9.0.0.0.

1.7.25 would be a good workaround for me except that I apparently need some ruby 2.1 features that it doesn't have a CompatVersion for.

@headius
Copy link
Member

headius commented Aug 12, 2016

Confirmed. It can be reproduced at a command line too:

$ jruby -e "instance_eval %[Kernel.eval 'def foo; end'; foo]"
NameError: undefined local variable or method `foo' for main:Object
Did you mean?  fork
         <eval> at (eval):1
  instance_eval at org/jruby/RubyBasicObject.java:1677
         <main> at -e:1

Something's up with the way instance_eval sets up the scope for method definitions.

@chadselph
Copy link
Author

Today I discovered that if you don't use eval without referencing Kernel, it actually works:

jruby -e "instance_eval %[eval 'def foo; end'; foo]"

Doesn't really help me, but how is that possible?

@headius
Copy link
Member

headius commented Aug 17, 2016

@chadselph That's a good clue! I'm going to step through the logic a bit today.

@headius
Copy link
Member

headius commented Aug 17, 2016

Ok, here's another clue: calling Kernel.foo works fine. So basically the method is getting defined on the singleton class of Kernel.

@headius
Copy link
Member

headius commented Aug 17, 2016

Maybe @subbuss or @enebo can refresh my memory about where we might start looking for this. I know we have punted on some bugs in the pass where someone does x.eval instead of eval, but is this a fixable case? Should Kernel.eval "def foo; end" define the method on Kernel's singleton class or as a instance method of Kernel?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants