-
-
Notifications
You must be signed in to change notification settings - Fork 925
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
java_import does not define top-level global when called from class method #975
Comments
java_import imports the constant into the current namespace. In this case it will add System to Util not to the calling context. To do what you want you could do something like: class Util
def self.import_stuff(context)
context.instance_eval do
java_import java.lang.System
end
end
end
Util.import_stuff(self)
p System So it is working as designed even if the side-effect of where the constant is defined may not seem so intuitive. |
Is this documented anywhere? The only documentation I find for java_import is the one I quoted before in the wiki, which specifically says "global name space", not "current namespace". Should it be changed? I'm not sure I understand what 'current namespace' even means with regard to this, though. module MyPackage ; end
class MyPackage::Util
def import_stuff
java_import java.lang.System
end
end
MyPackage::Util.new.import_stuff
::System # => Java::JavaLang::System Why is the 'current namespace' in that instance the top-level namespace (rather than |
Actually, I had to look at the source to actually believe this. If we are in a module we class_eval it so that it behave the way I described where in my parlance namespace == module/class it lives in. I actually thought if self was not a module we would define it with self's class. Unfortunately, it is not this straightforward. When self is not a module/class we will call a straight eval with a call to binding. This ends up getting you the behavior you showed in your last comment. I am pretty perplexed on why we do this. I have no doubt it was done for a reason but since I was not even aware of it we need to figure out why. As for documentation, I don't even see a reference to this in our book so I think I will reopen this issue at least until we can properly document the behavior. I might even prefer to change the behavior itself, but I would still like to understand the reason for it. |
Thanks for reopening! It does seem like a bug or undesirable behavior to me, but I understand your point that there may be a reason for it we are not currently aware of. |
Although if you're saying you want to change things to define in top-level namespace less frequently -- it might be backwards-breaking. Either way, what I think is really needed is more documentation on exactly how java_import is intended to work, including where it defines it's constants. Which would suggest the rules for where it defines it's constants should ideally be straightforward enough to document comprehensibly with a simple description! (I still don't entirely understand current behavior myself). When you say 'our book' -- is there jruby documentation somewhere I have not been aware of, what is this book? |
I agree we should document it which is why I re-opened this issue. The book I am referring to is "Using JRuby" published by Pragmatic Programmers. Since it does not appear to be documented online I was hoping we had covered this in our book. Unfortunately, not. |
The difference in behavior was so that both java_import within instance methods and java_import within class bodies would define the constant on the class. For example... java_import org.foo.Blah # toplevel, not a class, normal eval
class Quux
java_import org.foo.Blah # class body, class_eval
def Quux.some_class_method
java_import org.foo.Blah # self still === Class, class_eval
end
def some_instance_method
java_import org.foo.Blah # self !=== Class, normal eval
end
end I'm open to suggestions on a better-and-not-too-complicate heuristic. I think this is simply a documentation issue, though. |
Ah, wanting to define the constant within a certain class, when you do a
Right now, if you do a But anyway either way, backwards incompat changes prob don't make any sense at this point, but docs would be very welcome. The docs on |
FWIW this confusing behavior still applies to JRuby 9k
|
wiki had been edited since this was opened and I added an additional paragraph about using java_import from within methods (and also recommending people do not do it). |
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.6.0_51-b11-457-11M4509 [darwin-x86_64]
From the wiki,
However, this does not work when calling
java_import
from inside a class method.Is this a bug? Or is it somehow as designed? It would be convenient to be able to import java classes to top-level methods in utility methods like that. Oddly, it does seem to work if you do the
java_import
in an actual ordinary instance method, just not a class method.I suppose I could do my own stuff to somewhat confusingly dynamically set
the top level ::System constant to Util::System as a workaround, but it gets to be kind of confusing.
The text was updated successfully, but these errors were encountered: