Metaprogramming Techniques
前面已经讲述了Ruby的一些基础,后面是在Rails里面常见的元编程的技术。
尽管例子都是用Ruby书写的,这些技术大部分可以是对任何动态语言适用的。实际上,Ruby的元编程的语法是在像Lisp,Smalltalk和Perl里借鉴的。
运行时方法查找
我们经常需要的是创建一个根据一些运行时的数据变化的函数的接口。最突出的例子是Rails里面的ActiveRecord的属性的accessor方法。对ActiveReord的方法调用会在运行时被转化成属性的入口。在类—方法的层面上,ActiveRecord提供了相当好的便利:Person.find_all_by_user_id_and_active(42, true) 被转换成特定的SQL查询,当属性不存在的时候会引发一个标准的NoMethodError异常。
这个魔幻之处在于Ruby的method_missing方法。当一个不存在的方法被对象调用的时候,Ruby在引发标准的NoMethodError异常前首先检查对象类有没有method_missing方法。method_missing第一个参数是被调用的方法的名字;剩下的参数就是被调用的方法的参数。任何传递给那个方法的block会直接传给method_missing。一个万昌的函数签名如下:
def method_missing(method_id, *args, &block)
...
end
这里有使用method_missing的缺点:
它比常规的方法查找速度慢。一些简单的测试说明了带有method_missing方法的分派至少要比常会的分派在时间上多花费2到3倍。
因为被调用的方法实际上不存在——这种方法仅仅是在方法查找的最后一步解析的——因此不能向常规的方法一样被文档化和自省。
因为所有的动态的方法必须要通过method_missing方法,如果有很多的代码需要添加不同的方面动态的方法,method_missing方法的函数体会变的非常大。
使用method_missing限制了以后API的兼容性。一旦你依靠method_missing去处理没有方法定义的一些有趣的事情,在以后的API版本当加入新方法可能会破坏用户的预料。
在ActiveRecord里面用的generate_read_methods功能是一一个比较好的另一种方式。ActiveRecord不是等待method_missing去解析调用,而是生成一些属性setter和reader的实现,这些实现可以像常规的方法分派一样调用。
总体上来说,这是一个强大的方法,Ruby这种动态性让Ruby编写方法当方法第一次调用的时候用优化的版本替换自己的方法成为可能。Rails的routing需要快速响应,就用到了这个功能;这个在这一节的后面有描述。
Generative Programming: Writing Code On-the-Fly
一个对于其他的强大的技术是自产生编程——代码写代码
这个技术简单的说,就是写一个shell脚本去自动化一些单调编程。比如,你可能需要产生对每个用户测试装置。
brad_project:
id: 1
owner_id: 1
billing_status_id: 12
john_project:
id: 2
owner_id: 2
billing_status_id: 4
...
如果有一种语言没有可脚本化的测试装置,你必须手工来做。如果数据增加,这会变的杂乱,而且当有些很奇怪的原数据依赖的时候,这几乎不太可能手工做。单一的自产生编程可以让你在原数据里产生测试夹具。尽管不是很理想,这会在很大程度上改进手工书写。但是比较头疼的是维护:你必须把这个脚本合并在你的创建的过程里来保证这个夹具会在源数据变化时重新产生。
这个很少见,但在ROR里是需要的。几乎ROR所有的应用配置是可脚本化的,很大部分用了内部的DSL。在内部的DSL,在你可以使用Ruby全部的能力,不仅仅是库作者给你指定的特定接口。
回到先前的例子,ERb能让这个工作变的很容易。可在上面YAML文件里加入Ruby的代码(这些代码用ERb<% %>和<%= %>标记)和任何我们需要的逻辑:
<% User.find_all_by_active(true).each_with_index do |user, i| %>
<%= user.login %>_project:
id: <%= i %>
owner_id: <%= user.id %>
billing_status_id: <%= user.billing_status.id %>
<% end %>
对于这个小技巧,ActiveRecord's再简单不过了:
yaml = YAML::load(erb_render(yaml_string))
using the helper method erb_render:
def erb_render(fixture_content)
ERB.new(fixture_content).result
end
自产生变成常用 Module#define_method 或者 class_eval 和def区创建运行中的方法。ActiveRecord 对于属性的 accessors使用了这些技巧;generate_read_method噢共能定义了setter and reader方法,这些方法是ActiveRecord class的实例方法,能够减少使用times method_missing (a relatively expensive technique) 需要次数。
分享到:
- 2008-06-08 14:24
- 浏览 1232
- 评论(0)
- 论坛回复 / 浏览 (0 / 1621)
- 查看更多
相关推荐
"Advanced Rails" 涵盖了Rails开发中的高级主题和技术,是Ruby on Rails学习进阶的重要资源,尤其适合已经对基础Rails有一定了解的开发者。 在Web开发领域,Rails以其高效、简洁的代码和“约定优于配置”的哲学吸引...
本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是学习Ruby on Rails的理想选择。 ### 重要知识点概览 #### 1. Introducing Ruby on Rails(介绍Ruby on Rails) 这一章节...
### Ruby编程语言——基础知识与应用 #### 一、Ruby简介 《The Ruby Programming Language》是一本详细介绍Ruby语言的权威书籍,由Ruby之父Yukihiro Matsumoto(松本行弘)与著名技术作家David Flanagan共同撰写。...
- **目标读者**:本书面向的是对Ruby编程语言感兴趣的程序员和技术人员,无论是初学者还是高级用户都能从中受益。 - **主要内容**: - **Ruby基础知识**:包括语法、数据类型、流程控制等基础概念。 - **面向对象...
根据提供的文件信息,我们可以推断出这是一本关于高级Ruby on Rails编程的书籍,作者为Brad Ediger,并由O'Reilly Media出版。由于文件提供的内容有限,以下将基于已有的信息来总结并展开相关的知识点。 ### 一、...
Ruby是一种强大的动态编程语言,广泛用于Web开发,尤其是在Ruby on Rails框架中。为了在服务器环境中更好地利用Ruby,一些专门针对服务器优化的发行版被开发出来,以提高性能、减少资源消耗并简化管理。"Ruby-服务器...
2. **高级编程技巧**:除了介绍Rails的基础知识外,《Advanced Rails Reciples》还深入探讨了Rails框架中的高级编程技巧,如性能优化、安全性增强等。 3. **实战案例分析**:书中通过多个实战案例来展示如何将Rails...
通过阅读《Pragmatic Bookshelf Advanced Rails Recipes May 2008》,开发者可以掌握Rails的高级特性,提升他们的编程技巧,同时也能更好地理解Rails如何与其他Web开发框架相比较,从而在实际项目中做出更明智的技术...
这些资源涵盖了从基础到高级的Ruby编程知识,以及相关的Web开发框架Rails的内容。此外,还有诸如《Ajax on Rails》和《Ruby on Rails: Up and Running》等其他主题的书籍,显示了Ruby语言及其生态系统在Web开发领域...
O'Reilly Media是一家领先的科技图书出版商,除了《Ruby编程语言》外,还提供了多部与Ruby相关的著作,如《Ruby Cookbook》、《Learning Ruby》、《Advanced Rails》、《Rails Cookbook》、《Ruby Pocket Reference...
Rails是一个流行的开源Web应用框架,基于Ruby编程语言,它遵循模型-视图-控制器(MVC)架构模式,为开发者提供了构建高效、简洁的Web应用程序的能力。 在描述中提到的“博文链接:...
从描述中可以提炼出,这本书是入门Ruby的理想选择,书中内容覆盖了Ruby编程语言的基础知识,为读者打下坚实的基础。书中所涉及的内容可能包括但不限于Ruby语言的语法、数据类型、控制结构、模块、类和对象、异常处理...
在Ruby编程环境中,微信小程序的对称加密数据解密算法主要涉及到的是AES(Advanced Encryption Standard)加密技术。AES是一种广泛使用的块密码,以其安全性、效率和标准化而闻名。本项目"wechat_aes_sample_ruby-...
代码测验关于网站包含许多关于Ruby,Rails,JavaScript,Bash,Git等的编程实践问题! 当我学习编程时,我为自己创建了测验,并决定创建CodeQuizzes作为我的第一个Rails应用程序,以与世界分享这些测验。 现在,该...
1. **Ruby on Rails 框架与 RabbitMQ 的结合**:Ruby 社区最著名的框架是 Ruby on Rails,这些教程可能会讲解如何在 Rails 应用程序中设置 RabbitMQ,以实现后台任务处理、事件驱动架构或微服务通信。 2. **AMQP ...
1. **消息传递**:书中可能详细讲解了如何使用Ruby来构建消息传递系统,如通过AMQP(Advanced Message Queuing Protocol)或者RabbitMQ等中间件实现异步通信。消息队列在系统解耦和提高可扩展性方面扮演着重要角色。...
同时还提供了 OpenJDK 6、Tomcat 6、Ruby 1.8.7 和 Rails 3、PHP 5.3.2 与 Perl 5.10.1 等编程环境。 - **数据库支持**:为了满足企业级应用的需求,RHEL 6 提供了 PostgreSQL 8.4.4、MySQL 5.1.47 和 SQLite 3.6.20...