分享 分享些最近在看的关于 ruby 元编程文章

suffering · 2012年02月21日 · 最后由 Guest 回复于 2013年08月23日 · 5377 次阅读

分享些最近在看的关于 ruby 元编程文章 Ruby 里的元编程http://lifegoo.pluskid.org/?p=46 元编程的魅力——反射机制http://deathking.is-programmer.com/posts/24125 Ruby 元编程(零) http://deathking.is-programmer.com/posts/28864.html Ruby 元编程(一)实例变量、方法、类 http://deathking.is-programmer.com/posts/28861.html Ruby 元编程(二)方法的调用 http://deathking.is-programmer.com/posts/29059.html Ruby 元编程(三)实用元编程方法:内省、反射、send、define_method、method_missing、remove_method 和 undef_method、eval、instance_eval、module_eval、class_eval、class_variable_get, class_variable_set、class_variables、instance_variable_get、instance_variable_set、const_get、const_set http://deathking.is-programmer.com/posts/29100.html Ruby 元编程(四)绑定 http://deathking.is-programmer.com/posts/29141.html Ruby 元编程(五)块和绑定 http://deathking.is-programmer.com/posts/29146 Ruby 元编程(六)元编程实战 http://deathking.is-programmer.com/posts/29432.html

Design Beautiful Ruby Api http://www.slideshare.net/fullscreen/ihower/designing-ruby-apis/

感谢楼主,辛苦了

好帖!不一篇篇看一遍都觉得对不住楼主,希望这种知识分享多一些,已经帮忙放到 wiki 上了:http://ruby-china.org/wiki/ruby-meta

《Ruby 元编程》是讲解这个主题最为深入、权威的书籍: http://book.douban.com/subject/7056800/

@scriptfans 这本书都被翻译了啊,不过因为是 2010 年的书,所以不推荐看第二大节。第一大节还是蛮不错的。但不知道翻译的效果怎么样

这让人有点蛋疼,定义一个类方法,五种途径:

#1
class Person
  def self.species
    "Homo Sapien"
  end
end
#2
class Person
  def Person.species
    "Homo Sapien"
  end
end
#3
class Person
  class << self
    def species
      "Homo Sapien"
    end
  end
end
#4 
class << Person
  def species
    "Homo Sapien"
  end
end
#5
Person.instance_eval do
  def species
    "Homo Sapien"
  end
end

以上引自代码示例引自http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/,略有改动。 定义一个类方法而已,为什么要有这么多种方法存在? 如果再加上一种变态的 class_eval 的示例:

#6
class Foo
end
metaclass = (class << Foo; self; end)
metaclass.class_eval do
    def species
      "Homo Sapien"
    end
  end
end

.....那就是 6 种方法了. 而后,这数种方法,在定义方法的范围,self 指代不同的对象,有的指向 Foo 类,有的则指向 Foo 类的 metaclass.有的打开了一个新的 scope(可以调用外面的变量),而有的则不可以. 用 yehada katg 的话来说:'At this point in other articles on this topic, you’re probably struggling to keep all of the details in your head; it seems as though there are so many rules.' 这么多规则让人怎么记它 ! 让人怎么不弄乱它! 一项操作,弄 6 种(可能更多)solution 出来,有必要吗?值得吗? 事实上,有必要的。因为这数种方法虽然在效果上看起来没有区别 (不就是定义了个类方法吗!).但实际上这中间的细微差异 (self 的不同,scope 的不同) 是为不同的要求而特意设计的。比如说,元编程. 这里举个例子:

name = "foo"
var = "bar"
metaclass = (class << String; self; end)
metaclass.class_eval do
  define_method(name) do
    puts var
  end
end
String.foo # bar

这里,因为 class_eval 开了一个新的 scope,所以,可以直接调用之前调用之外的变量 name 与 var.而这样做却是不行的:

name = "foo"
var = "bar"
class Foo
  define_method(name) do
    puts var
  end
end
Foo.foo # bar

这样也不行:

name = "foo"
var = "bar"
class Foo
  class << self
    define_method(name) do
      puts var
    end
  end
end
Foo.foo # bar

因为class Foo, class<<Foo, class Foo;def self.bar;end;end, 以及class Foo;def Foo.bar;end;end这几种方式都打开了新的 scope(作用域).直接的结果是,对外部环境的 scope 调用不着。

哪一天你需要这样用元编程,但是不知道如果控制作用域,what are you going to do?定义一个动态存取的实例变量?或者干脆用类变量?

事实上,对这些细节的使用,远远不只元编程这么个例子这么简单。在开发的过程中,你永远不知道下一刻你会遇到多诡异的要求。当然,大部分情况下你可以想出办法来解决这些问题。但是,很多时候,最直接有效的解决办法可能就直接隐藏在这些小细节里。引用乔帮主的一句话:you can't connect the dots looking forward;you can only connect them looking backwards

扯了这么多,只是要分享一点心得:多种途径实现一种方法,并不是给你的大脑加负的。而是为了实现强大的功能而特意设计的.多途径得出的结果,看似效果相同,实际上,却隐藏了许多细微的差别。而这种设计的目的,就是为了让我们能根据不同的需要,利用这些差异更便利地得到自己想要的。

最后,再次推荐一下:http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/ 这里面的探讨很深入,有助于大家进一步理解。

#6 楼 @raykin 翻译还不错,我做过全文审读,放心吧。讲 rails 的部分,其实也不算过时,看看以前的元编程应用也还是能学到不少知识的。

is-programmer.com 也是 ruby on rails 开发的。而且是从 2.x 版本开始。

@scriptfans :-),那本书我在 2010 年就看过两遍了。讲 rails 的部分,我个人是不大推荐看的,因为我比较崇尚务实。当然看看肯定是有好处的,因为作者的确是个深入浅出的高手。我顺带看了下豆瓣里的点评,有人讲这是晋级高阶 ruby 的必读书,我个人是很赞同的。

11 楼 已删除
需要 登录 后方可回复, 如果你还没有账号请 注册新账号