跨越边界: 活动记录和Java编程中特定于域的语言 - 编程入门网
; my_attr :name
irb(main):004:1> end
=> nil
irb(main):005:0> person = Person.new
=> #<Person:0x2b5fb90>
irb(main):006:0> person.name = "Bruce"
=> "Bruce"
irb(main):007:0> person.name
=> "Bruce"
正如所期望的,可以把行为添加到任何现有类。现在看到了怎样才能把行为绑定到可以添加到类的附 加功能上。这项技术就是活动目录添加高级概念(例如 belongs_to 和 has_many)的方式。但是活动记 录没有把行为添加到类,而是添加到叫作 ActiveRecord::Base 的模块。 现在已经看到了一些相当精密的功能的作用,但是 Ruby 还能做更多支持 DSL 的事。 method_missing 和动态行为 有时,想根据外部情况把方法添加到类。例如,假设想在 Ruby 中表示罗马数字。要把它们与字符串 分开,可以用 Roman.III 的形式把数字 3 表示成罗马数字。要为每个可能的罗马数字都向 Roman 添加 类方法,是不现实的,而且使用 Ruby 时也不需要这么做。可以利用一个小技巧。 在 Ruby 中,在遗漏了一个方法时,Ruby 就会调用 method_missing 方法。可以覆盖它来提供罗马数 字,如清单 8 所示: 清单 8. 覆盖 method_missing 方法
这个代码相当简单,但是确实使用了 Java 程序员不熟悉的一些 Ruby 特性。由于覆盖了 method_missing,所以只要这个类的客户调用一个不存在的方法,Ruby 就会调用这个方法。下面说明细 节: 使用两个参数: name 代表方法名 *args 代表遗漏方法的参数 name 是个符号,所以首先用 to_s 把它转换成 String。 用正则表达式进行数字是否罗马数字的合理猜测。 如果数字是罗马数字,就进行一系列替换,让罗马数字更容易处理。IV 是 4 ,IX 是 9,所以只计算 X、V 和 I 的出现,还不能得到它们的值。 为罗马字母的每次出现分配一个值,分别是:I(1)、V(5)、X(10)、 L(50)或 C(100)。 如果方法不是罗马数字,就调用超类,超类报告方法遗失。 对于 DSL,这个技术极为强大。活动记录使用这个功能实现动态查找器。活动记录没有为每个列实际 地添加查找器,而是使用了 method_missing。使用这个策略,活动记录不仅能匹配一个列,还能匹配列 的组合。例如,把 name 和 email 列添加到 people 表,可以支持 Person 类的 People.find_by_name_and_email 查找器。像这样的细节使得活动记录的用户体验非常舒服。它们也让活 动记录的实现非常简洁而有意义,所以在活动记录做的工作不符合自己的要求时,随时可以实现自己的补 丁。 跨越边界: 活动记录和Java编程中特定于域的语言(5)时间:2011-07-25 IBM Bruce TateJava 编程中的 DSL 回顾 在使用 Java 语言时,选项就非常有限了。元编程更困难,所以很少能够得到活动记录那样的体验。 但是如果真的急需 DSL,还是有些选项的。而且不用总是求助于 XML 或标注。下面是一些常用的方法: 对于需求不太迫切的 DSL,可以使用 Java 类、方法和名称构建对英语友好的词汇,并通过消息调用 做需要的事。 对于典型的 Java 用 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |