元编程摘要:速度,Ruby宏,视频教程

Matt Aimonetti刚贴了篇文章 元编程速度初探来讲述定义方法的不同对速度造成影响。他发现使用 define_method定义工具 方法 的运行速度比静态定义的方法(例如使用 def method_name定义的方法) 慢得多

但是,文章 后续报道:Matt找到了原因和解决方案中关于速度的结论又有不同。速度不同的原因是:
今天Wycats告诉我原因在于define_method:class_eval的效率和常规代码一样高,和常规的Ruby代码一样,它也是在eval.c中被计算的;而define_method则需要编译proc。
Matt将上面的性能评测程序使用class_eval进行修改,给出了此程序的更新版本,这个版本的性能与静态定义方法的程序性能已经没什么不同。对于元编程工作来说,这是一个非常有用的经验。

元编程领域的另一个极端是 Reginald Braithwaite的 重写gem系 列。重写gem采用来自于LISP或Scheme的,被称为宏或宏展开的方法。对于Ruby来说,这种方法需要稍微跨出Ruby语言——常规Ruby代码 并不允许访问已经被载入的Ruby代码——反射止步于方法这一层次。在MRI 1.8中,使用ParseTree扩展来访问代码(从Ruby解析器中得到抽象语法树(AST))。Rubinius提供对ParseTree的s- exprs形式的支持(例如调试器支持对于方法的s-exprs进行访问)。对于JRuby也有一个不完整的Parse Tree版本(它不支持对于特定方法类型的抽象语法树的访问)。ParseTree并不支持Ruby 1.9。

重写gem中具体的方法常用来解决特定的问题,但其中的原理的应用将更加广泛。现在需要解决的问题是向类中添加方法(开放类),这是个系统问题。例如有一段代码,作为一个方法foo加入到Object中,这个方法在运行时对于所有代码都是可见的——这会导致一些诸如命名冲突的问题(如果有另一个同名方法已经 存在于这个类中)。

重写gem的解决方法是:将此新添加的方法的可见性限制于一个块中,例如 这样:
with(andand) do
 foo().andand.bar(blitz())
end
使用with语句处理的在块中的语句被转换为ParseTree的s-exprs形式,继而被分析及重写。在这种情况下,在其他地方并没有一个叫做 andan d的方法——在块中,with语句调用并重写这个方法,从而得到期待的行为。

需要记住的是,重写gem中的实现只是以一种方式,还有更多的方法可以让我们在Ruby中体验宏的魅力。尽管Ruby关于块的便捷的语法可以容易地做到精确的标记,但传入太多的需要延迟评估的代码会使情况变得很复杂:这需要更多的冗长的方法创建Proc。

对于像宏这样的概念的介绍, "Common Lisp实践"是个不错的开始。还有一些项目应用ParseTree以分析代码—— InfoQ展示Ambition、Sequel和merb如何使用ParseTree。另外请参考 Joel Klein的讨论——涉及延迟评估lambda算子部分,这里介绍了宏和Lambda演算。

最后,对于不熟悉用Rudy进行元编程的人, Dave Thomas(PragDave)的这一系列视频教程介绍了相关概念,本系列视频教程已经获得了一些正面的评价。

查看英文原文: Metaprogramming Roundup: Speed, Ruby Macros, Screencasts

你可能感兴趣的:(元编程摘要:速度,Ruby宏,视频教程)