Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例

上传人:李*** 文档编号:112418924 上传时间:2022-06-22 格式:DOC 页数:8 大小:21.50KB
收藏 版权申诉 举报 下载
Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例_第1页
第1页 / 共8页
Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例_第2页
第2页 / 共8页
Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例_第3页
第3页 / 共8页
资源描述:

《Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例》由会员分享,可在线阅读,更多相关《Ruby元编程之梦中情人methodmissing方法详解shell脚本编程100例(8页珍藏版)》请在装配图网上搜索。

1、Ruby元编程之梦中情人method-missing方法详解shell脚本编程100例这篇文章主要介绍了Ruby元编程之梦中情人methodmissing方法详解,本文讲解了我该怎么用 methodmissing 、方法代理、definemethod、什么时候用 methodmissing、元方法等内容,需要的朋友可以参考下我最近读了些文章(比方这篇),宣传在 Ruby 里使用 methodmissing 的。很多人都与 methodmissing 干柴烈火,但在并没有小心处理彼此之间的关系。所以,我想来讨论一下这个问题:我该怎么用 methodmissing 什么时候该抵挡 methodmi

2、ssing 的诱惑首先,永远不要在还没花时间考虑你用得够不够好之前,就向 methodmissing 的魅力屈从。你知道,在日常生活中,很少会让你以为的那样亟需 methodmissing:日常:方法代理案例:我需要让这个类可以使用另一个类的方法这是我所见过最普遍的使用 methodmissing 的情况。这在 gems 与 Rails 插件里头尤其流行。它的模型类似这样:代码如下:class Adef hiputs “Hi from #self.class”endendclass Bdef initializeb = A.newenddef methodmissing(methodname,

3、 args, block)b.send(methodname, args, block)endendA.new.hi #= Hi from AB.new.hi #= Hi from A如此,B 就拥有了 A 的所有实例方法。但是让我们想想,在调用 b.hi 的时候都发生了什么。你的 ruby 环境沿着继承链一路找 hi 这个方法,到最后,恰恰在丢出个 NoMethodError 前,它调了 methodmissing 这个方法。在上例中,情况并不坏,毕竟这里就两个微缺乏道的类需要查。但通常,我们是在 Rails 或者其他一些框架的上下文中编程。而你的 Rails 模型继承自 ActiveRec

4、ord,而它又集成自其他一大坨的类,于是如今你就有了一坨高高的堆栈要爬 在你每次调用 b.hi 的时候!你的好基友:definemethod估计如今你在抱怨,“但是史蒂夫,我需要 methodmissing” 我告诉你,别忘了其实除了情妇之外,你还有个忠诚的好基友,叫做 definemethod。它允许你动态地定义一个方法(顾名思义)。它的伟大之处在于,在它执行过之后(通常在你的类们加载之后),这些方法就存在你的类中了,简单直接。在你创立这些方法的时候,也没有什么继承链需要爬。definemethod 很有爱很可靠,并且可以满足你的日常生活。不信我?接着看代码如下:class Bdefinem

5、ethod(:hi) dob.hiendend“可是我有一大坨方法要定义!” 你抱怨“没问题!” 我卖萌眨眼代码如下:class B:hi, :bye, :achoo, :gesundheit.each do |name|definemethod(name) dob.send(name)endendend可是我懒得把它们一个个写出来!你有点难搞哦代码如下:class A# lots of methods in hereendclass BA.instancemethods.each do |name|definemethod(name) dob.send(name)endendend那假设我要

6、定义的方法跟本来的有那么一些些不一样呢?容易代码如下:class Adef hiputs “Hi.”endendclass BA.instancemethods.each do |name|definemethod(“whatis#name”) doif b.respondto?(name)b.send(name)elsefalseendendendendB.new.whatishi #= “Hi.”B.new.whatiswtf #= false呃,代码看起来不优雅啊那就没方法了,凑合得了。假如你想要代码更易读,可以看看我们的ruby delegation library 和 Rails A

7、ctiveRecord delegation。好,我们总结一下,看看 definemethod 的真正威力。修改自 ruby- 上的 例子代码如下:class Adef fredputs “In Fred”enddef createmethod(name, block)self.class.send(:definemethod, name, block)enddefinemethod(:wilma) puts “Charge it!” endclass B In Freda.wilma #= Charge it!a.createmethod(:betty) p self.tos a.betty

8、 #= B什么时候用 methodmissing?如今你估计在想,总有该用它的时候吧,不然还要它干嘛?没错。动态命名的方法(又名,元方法)案例:我要根据某种形式提供一组方法。这些方法做的事情顾名思义。我可能从来没有调用过这些可能的方法,但是等我要用的时候,它们必须可用。如今才是人话!这其实正是 ActiveRecord 所采用的方式,为你提供那些基于属性的动态构建的查找方法,比方 findbylonandemail(userlon, useremail)。代码如下:def methodmissing(methodid, arguments, block)if match = DynamFind

9、erMatch.match(methodid)attributenames = match.attributenamessuper unless allattributeseists?(attributenames)if match.finder?# you get the pointend # my OCD makes me unable to omit this# elsesuper # this is important, Ill tell you why in a secondendend权衡利弊当你有一大堆元方法要定义,又不一定用得到的时候,methodmissing 是个完美的折衷

10、。想想 ActiveRecord 中基于属性的查找方法。要用 definemethod 从头到脚定义这些方法,ActiveRecord 需要检查每个模型的表中所有的字段,并为每个可能的字段组合方式都定义方法。代码如下:findbyemailfindbylonfindbynamefindbyidfindbyemailandlonfindbyemailandlonandnamefindbyemailandname# 假设你的模型有 10 个字段,那就是 10! (362880)个查找方法需要定义。想象一下,在你的 Rails 工程跑起来的时候,有这么多个方法需要一次定义掉,而 ruby 环境还得把

11、它们都放在内存里头。老虎伍兹都做不来的事情。正确的 methodmissing 使用方式(译者猥琐地注:要回家了,以下简要摘译)1、先检查并不是每次调用都要处理的,你应该先检查一下这次调用是否符合你需要添加的元方法的形式:代码如下:def methodmissing(methodid, arguments, block)if methodid.tos = /whatisw+/# do your thingendend2、包起来检查好了,确实要处理的,请记得把函数体包在你的好基友,definemethod 里面。如此,下次就不用找情妇了:代码如下:def methodmissing(method

12、id, arguments, block)if methodid.tos = /whatisw+/self.class.send :definemethod, methodid do# do your thingendself.send(methodid)endend3、擦屁股自己处理不来的方法,可能父类有方法,所以 super 一下:代码如下:def methodmissing(methodid, arguments, block)if methodid.tos = /whatisw+/self.class.send :definemethod, methodid do# do your t

13、hingendself.send(methodid)elsesuperendend4、昭告天下代码如下:def respondto?(methodid, includeprivate = false)if methodid.tos = /whatisw+/trueelsesuperendend要告诉别人,你的类虽然暂时还没有这个方法,但是其实是可以响应这方法的。总结 在每个 Ruby 程序员的生活中,这仨方法扮演了重要的角色。definemethod 是你的好基友,methodmissing 是个如胶似漆但也需相敬如宾的情妇,而 respondto? 那么是你的爱子,如此无虞。第 8 页 共 8 页

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!