`
Hooopo
  • 浏览: 329372 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

reduce method missing call stack with dynamic define method

    博客分类:
  • Ruby
阅读更多
method_missing是ruby里面一个非常cool的hook。rails里面很多特性都是基于method missing实现的。
但是method missing也不是那么完美。各种rails性能优化的文章都建议避免使用method missing,原因很简单,method missing的实现机制确实会是增加call ruby stack次数。

使用method missing + define method,调用一次method missing后动态定义方法来减少call ruby stack次数。
class A
  def method_missing(method_id, *args)
    puts "method missing stack called.."
    if  method_id.to_s =~ /^find_by_(.*?)$/ 
      name = $1
      self.class.send(:define_method, method_id) do
        name
      end
      send(method_id, *args)
    else
      super
    end
  end
end
obj = A.new
p obj.find_by_title
p obj.find_by_title                     


输出:
method missing stack called..
"title"
"title" #第二次没有执行method missing方法..


rails里的find by和动态属性都是这样实现的:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods.rb
分享到:
评论
5 楼 Hooopo 2011-07-02  
A  trick to reduce the number of calls to method_missing from tenderlove:
http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary/
4 楼 orcl_zhang 2011-06-10  
Hooopo 写道
orcl_zhang 写道
这个会不会覆盖掉其他方法?
而且会增加很多无用的方法吧。

1.当然不会。。因为是在methodmissing执行时候才能定义方法的
比如A.new.find_by_name("Hooopo"),执行过程是这样的:
第一次执行:这个方法不存在->执行method missing->定义方法find_by_name
第二次执行:直接调用find_by_name

2.拿find_by_database_colum这个需求来说,数据库字段个数是有限的。需要使用find by的场景更是有限的,一般就是find by id/name/uid等


哦,看错了。。
想成(:define_method, name)了。。

chloerei 写道
Metaprogramming Ruby 里面也用了这个例子 http://book.douban.com/subject/4086938/ 好书

 
3 楼 chloerei 2011-06-10  
Metaprogramming Ruby 里面也用了这个例子 http://book.douban.com/subject/4086938/ 好书
2 楼 Hooopo 2011-06-10  
orcl_zhang 写道
这个会不会覆盖掉其他方法?
而且会增加很多无用的方法吧。

1.当然不会。。因为是在methodmissing执行时候才能定义方法的
比如A.new.find_by_name("Hooopo"),执行过程是这样的:
第一次执行:这个方法不存在->执行method missing->定义方法find_by_name
第二次执行:直接调用find_by_name

2.拿find_by_database_colum这个需求来说,数据库字段个数是有限的。需要使用find by的场景更是有限的,一般就是find by id/name/uid等

1 楼 orcl_zhang 2011-06-10  
这个会不会覆盖掉其他方法?
而且会增加很多无用的方法吧。

相关推荐

Global site tag (gtag.js) - Google Analytics