fredag, oktober 06, 2006

JRuby import

OK, for those of you who thought that importing a class into the current namespace by assigning a constant, here is a small implementation (based on include_class), that lets you use import like you do it in Java:
 require 'java'

class Object
def import(name)
unless String === name
name = name.java_class.inspect
class_name = name.match(/((.*)\.)?([^\.]*)/)[3]
clazz = self.kind_of?(Module) ? self : self.class
unless clazz.const_defined?(class_name)
if (respond_to?(:class_eval, true))
class_eval("#{class_name} = #{name}")
eval("#{class_name} = #{name}")

import java.util.TreeMap

x =
x['foo'] = 'bar'
puts x

5 kommentarer:

yan sa...

Thanks Ola! Very cool. This seems a pretty clean way to do it..and makes sense in my brain. I thought I would somehow have to access the caller's bindings using the Kernel#bindings method, but this makes sense too...maybe even more sense

yan sa...

Ola, I'm not sure I understand why you check whether class_eval is available. Is that like a scope check to see if you're executing inside a class?

Eugene Kuleshov sa...

How about "import static" like construct? ;-)

Rich Apodaca sa...

Very nice article, Ola. I also liked the one listing 11 Ruby metaprogramming techniques.

As a variation on this approach, I've written a tutorial that shows how to map Java package names onto Ruby modules using Ruby Java Bridge.

Gladys Wickerbottom sa...

Mmm.. Don't know if I quiote agree with you.. But I don't have a good argument against you yet :)

DJ Perth Drop by and visit us some time..