`
RednaxelaFX
  • 浏览: 3048205 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

JRuby的类重定义……为什么不行?

    博客分类:
  • Ruby
阅读更多
在jirb里想试试这个的:
class java.lang.Integer
  def +(rhs)
    self.int_value() + rhs
  end
end

但是jirb总是提示self.int_value() + rhs那行有错。到底是为什么呢?

我也就是想这样而已……
irb(main):001:0> i = java.lang.Integer.new(1) # OK
irb(main):002:0> i
=> #<Java::JavaLang::Integer:0x1fbc355 @java_object=1>
irb(main):003:0> i.java_class
=> java.lang.Integer
irb(main):004:0> i.int_value
=> 1
irb(main):005:0> i + 2     # not impl'd
=> 3                       # what I'd like to see


结果我发现我犯了个超低级的错误。JRuby实现java.lang.Integer这样的类型访问实际上是通过method_missing机制,先是对java这个方法进行调用,方法不存在而通过method_missing机制,转换成一个值返回过来;然后对这个返回值调用其lang方法(或者还是说“发送"lang"消息”更合适?),不存在,于是在method_missing里做了点手脚来找到对应的package并返回又一个值,再调用Integer方法,同样是不存在然后通过method_missing找到对应的Java类。

在jirb里试试这个就知道上面说的是什么了:
irb(main):001:0> java
=> Java::Java
irb(main):002:0> java()
=> Java::Java
irb(main):003:0> com
=> Java::Com
irb(main):004:0> com().sun()
=> Java::ComSun

这里的java啊com啊什么的都不是变量,而是不存在的方法而已。

于是,java.lang.Integer只是个会返回一个值的一连串方法调用。Java::JavaLang::Integer才是这个Java类在JRuby里的名字。形式是:
引用
Java::FullPackageNameInCamelCase::ClassName


明白了这点之后,只要把上面的代码改一句就行:
irb(main):001:0> class Java::JavaLang::Integer # 改了这里
irb(main):002:1>   def +(rhs)
irb(main):003:2>     self.int_value + rhs
irb(main):004:2>   end
irb(main):005:1> end
=> nil
irb(main):006:0> i = java.lang.Integer.new 2
=> #<Java::JavaLang::Integer:0x7efa96 @java_object=2>
irb(main):007:0> i + 3
=> 5


T T 这种集成方法还是稍微surprise了一下。
不过回过头来想想,IronRuby/DLR的做法跟这个在表现上非常相似,但具体做法不同。JRuby主要通过method_missing机制,而IronRuby/dlr则通过注入全局变量:可以在host里为脚本运行环境注入一个名为System的NamespaceTracker类型全局变量,它会自动找到System下面的各个类以及各个子命名空间。我还是玩DLR的时间更多些,对IronRuby也比对JRuby更熟悉些。可惜现在的IronRuby离真正“能用”差得还好远。
在John Lam的blog上的一篇文章,Dynamic Silverlight Part 3: Integrating Silverlight with ASP.NET MVC里,就有这种要在IronRuby的代码里复写.NET原有类型的方法的使用场景:
silverlight.rb:
class UIElement
  alias_method :old_render_transform_origin=,
               :render_transform_origin=

  def render_transform_origin=(point)
    self.old_render_transform_origin = Point.new(point.first, point.last)
  end
end

类名直接就UIElement了(多好 T T
UIElement是Silverlight/WPF的一个类。这里是要给RenderTransformOrigin方法写一个adaptor,让它的参数类型从WPF的Point改变为Ruby的数组,让整个类用起来更“Ruby”。很有趣。
当然前面是有相应的require的。JRuby在做了合适的require之后也能达到类似的效果。
分享到:
评论
4 楼 RednaxelaFX 2008-06-19  
嘛,wiki上那个也算不上正式文档,而且有点过时了。有些已经deprecated的东西还在上面(而没提到deprecated的状态),例如说include_package。
Practical JRuby On Rails Web 2.0 Projects: Bringing Ruby On Rails To Java一书的附录里的介绍至少就比wiki上的新。有机会再写点什么详细点讨论这个。
3 楼 dennis_zane 2008-06-19  
yangzhihuan 写道
受教了,不太明白jruby对java类的命名,看到这一句:
Java::FullPackageNameInCamelCase::ClassName
有种恍然大悟的感觉.
jruby貌似没有一个正式的文档去说明一下怎么把java集成到jruby中.

wiki上都说的那么详细了,你还要他们怎么说
2 楼 RednaxelaFX 2008-06-17  
正式的文档我也没见到,不过也不能怪那些在业余时间坚持开发的开发者。
Sun虽然聘请了Thomas Enebo和Charles Nutter,不过整个小组应该还是人力不足吧?

话说这帖原本有个地方有个重要的错误:原帖里我是说java.lang.Integer这样的类型访问中java是一个变量,不过其实不是的。这里java也是一个方法,是一个不存在的方法。上面已经修正更新了……
1 楼 yangzhihuan 2008-06-16  
受教了,不太明白jruby对java类的命名,看到这一句:
Java::FullPackageNameInCamelCase::ClassName
有种恍然大悟的感觉.
jruby貌似没有一个正式的文档去说明一下怎么把java集成到jruby中.

相关推荐

    org.jruby.rar

    2. 类加载:JRuby 使用 Java 类加载器来加载 Ruby 类,使得 Ruby 对象可以与 Java 对象无缝交互。 【知识点四:JRuby 的部署和集成】 1. WAR 包:JRuby 应用可以被打包成 WAR 文件,部署在任何支持 Java Web 应用...

    jruby1.7.8版本呢

    - **Java 类型映射**:JRuby 自动将 Ruby 类型映射为对应的 Java 类型,例如 Ruby 数组映射为 Java 数组。 **5. 结合 JRuby 实现企业级应用** JRuby 的 Java 集成能力使其在构建企业级应用时具有独特优势。例如,...

    如何安装与配置JRuby

    2. **编写并运行 "Hello World"**: 创建一个名为 `HelloWorld.rb` 的文件,输入 `puts "Hello world"`,然后在 CMD 中运行 `jruby HelloWorld.rb`,你应该能看到 "Hello world" 的输出。 3. **调用 Java 类**: 修改 ...

    jruby-1.7.9.zip

    为什么选择在 Java 平台上运行 Ruby? 3. **OpenCMS**:OpenCMS 的核心功能是什么?它如何帮助开发者构建和管理网站?有哪些关键特性,如内容创建、版本控制、权限管理等? 4. **Web 应用的部署**:"war" 文件的...

    jruby-src-1.0

    这对于学习如何在Java环境中实现动态语言,或者想要为JRuby贡献代码的人来说是极其宝贵的资源。 此外,标签“eclipse-jruby”暗示了可能有一个Eclipse插件用于支持JRuby的开发。Eclipse是一款流行的开源集成开发...

    jruby-bin-1.3.1.zip

    这个“jruby-bin-1.3.1.zip”压缩包是JRuby的一个早期版本,专为Ruby语言的研发提供必要的工具和环境。在这个版本中,重点是兼容性、性能和稳定性。 1. JRuby的介绍: JRuby是一种开源的、完全兼容MRI(Matz Ruby ...

    JRuby+Swing是开发人员钟情的选择

    1. **定义视图**:使用 Java Swing 类定义 UI 组件和布局。 2. **编写控制器**:用 Ruby 写出处理用户交互的逻辑。 3. **绑定视图与控制器**:Monkeybars 将这两部分连接起来,确保数据同步和事件处理。 虽然 ...

    如何监控JRuby脚本的执行

    - `-Djruby.script=jruby`:指定执行的脚本为JRuby。 - `-Djruby.thread.pooling=true`:开启线程池。 - `-Djruby.jit.threshold=0`:设置即时编译的阈值。 - `-Djruby.compile.fastest=true`:开启最快的编译模式。...

    jruby_windows1.7and bin1.7

    jruby安装包 和 jruby的lib库 JRuby是面向Ruby、基于Java虚拟机(JVM)的一种解释程序,它结合了Ruby语言的简易性和功能强大的JVM的执行机制,包括与Java库 全面集成。Rails彻底加快及简化了Web应用的开发,不过它让...

    jruby_windows_1_6_4安装文件

    5. **并发性**:JVM的线程模型为JRuby提供了良好的并发支持,适合处理高并发场景。 **JRuby 1.6.4版本特性** - **稳定性增强**:1.6.4版本相对于早期版本,可能包含了一些关键的bug修复和性能改进,使得JRuby在...

    jRuby On Rails WEB2.0

    作为JRuby项目的领头人和核心开发者,Ola Bini以其丰富的经验和深刻的洞察力,为读者提供了一套实用的方法论和项目案例,旨在帮助Java开发者掌握jRuby技术,从而在企业级Java应用中无缝集成Ruby on Rails。...

    Ruby-JRuby一个Ruby语言的Java实现

    JRuby的实现方式是将Ruby源代码转换为Java字节码,然后在JVM上执行。这种转换过程涉及到词法分析、语法解析、抽象语法树(AST)构建以及最终的字节码生成。JRuby还支持Just-In-Time(JIT)编译,这意味着频繁执行的...

    走近JRuby

    1. **JRuby简介**:介绍JRuby的历史、开发背景、主要特性,以及为什么选择JRuby而不是其他Ruby实现。 2. **JRuby与Java的结合**:阐述JRuby如何在JVM上运行,包括类加载机制、垃圾回收以及与Java类库的交互。 3. *...

    jruby-complete-1.7.19.jar

    jruby-complete-1.7.19.jar,java版本的ruby解析器

    jruby-1.3.1.jar

    jruby-1.3.1.jar包 解决org.jruby.exceptions.JumpException 等报错

    jruby-1.5.5+OperaWatir+RSpec

    标题 "jruby-1.5.5+OperaWatir+RSpec" 暗示了这是一个关于使用 JRuby 1.5.5 版本、OperaWatir 和 RSpec 进行自动化测试的项目或者资源集合。现在,我们将深入探讨这三个关键组件以及它们在 IT 领域中的应用。 JRuby...

    jruby-bin-0.9.0.tar.gz

    **标题解析:**"jruby-bin-0.9.0.tar.gz" 是一个压缩文件,其中包含JRUBY的可执行二进制版本,版本号为0.9.0。JRUBY是Ruby编程语言的一个实现,它允许在Java平台上运行Ruby代码。 **描述解读:**描述中提到“Ruby...

    JRuby 实战入门

    **JRuby实战入门** 在IT领域,Ruby是一种高级、动态、面向对象的脚本语言,以其简洁、优雅的语法和强大的元...在实践中不断探索,你会发现JRuby为你带来的不仅仅是语言的转换,更是一种全新的开发体验和无限的可能。

Global site tag (gtag.js) - Google Analytics