您好,登录后才能下订单哦!
这篇文章主要介绍“Ruby2.1中Refinements特性有哪些”,在日常操作中,相信很多人在Ruby2.1中Refinements特性有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Ruby2.1中Refinements特性有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Monkey Patches(猴子补丁)一直是Ruby Open Class(开放类)特性的副作用, 不过也有人把Monkey Patches看作是Ruby的一种特性。为什么叫「猴子补丁」呢? 进化未完全呗,这也是Ruby社区中传出来的名字,不管如何,这个命名代表着贬义,意味着危险。
Ruby的开放类给开发者以很大的自由与灵活,但是,当你打开一个类,添加自己的方法的时候,你有没有想过这个方法会覆盖掉已有的方法,自己写的代码还好,但是你如果用Ruby内建的类,或者是第三方gem提供的类,Monkey Patches随时有可能让你的代码穿越。
有一个比较典型的案例,早年的Ruby1.8.7 preview版本之前,是没有Symbol#to_proc这个方法的,但是Rails自己通过Monkey Patch实现了Symbol#to_proc方法,结果Ruby1.8.7preview版本之后,添加了Symbol#to_proc方法,导致了Rails出现了一些不对劲的问题。
在Refinements出现之前,Ruby社区避免Monkey Patches的方法基本有以下几种:
使用别名/ alias_method_chain
使用module 加命名空间
强制检查要添加的方法是否被定义
Ruby社区里讨论了好多年的Refinements特性,就是为了解决上述问题,让你安全的使用开放类。直到Ruby2.0才加进来这个特性,但是属于实验性的,不建议使用,但是前两天随着Ruby2.1稳定版的发布,Refinements特性解除了实验状态,意味着Ruby团队支持建议你去使用Refinements特性了,但是比较悲剧的是, Refinements的文档没有跟上,你要去看文档学习这个新特性的话,多半会出错。
下面我总结了一下Ruby2.1中Refinements的大致用法,如有遗漏,请告诉我。
可见, 你使用了Module#refine方法打开类去增加的方法,只能使用Module#using方法在需要使用这个补丁的地方,引入补丁模块,才可以使用。而且,注意上面的示例代码,你必须在类定义的原始地方去using NumberQuery才起作用。这有点类似java或.net中的概念,Classboxes,即classbox的修改只对本classbox(或者导入它的 classbox)是可见的,这个特性我们称之为本地重绑定(local rebinding)。 C#里ms也有一个using,用于扩展方法, C#的扩展方法仅仅在其显式导入的代码中才是可见的, 这也和我们上面的Ruby示例相似。所以Ruby中的Refinements算是改进版的Classboxes了。
然后:
当然,这不会造成String类全局的污染,只限于other_method方法,但是,请注意,你是不是有惯性的打开类进行Monkey Patches了?
有人可能这么用:
哥,拜托,这样是会报错的:
这意味着,你不能在一个类中去使用refine。
还有人有点小聪明,他这么用:
这样是行不通的, 还是去学学普通青年的用法吧,NumberQuery#hello方法中使用的number?是不合法的。
还有人在想,这多麻烦啊,还得写两遍模块的名字,有了,我用included方法:
打住吧,兄弟,你又犯二了,睁大眼睛看看报的什么错吧!
有位兄弟,想定义个类方法:
傻眼了吧? 呵呵,告诉你正确的定义类方法的用法:
这次正常了。
Refinements还有个容易令Rubyist犯二的地方,就是你refine的方法,如果和类中的方法重名,还是会重写掉那个方法的,当然你可以也使用super。
String#to_s的方法被修改了,唉,难道这又是Monkey Patches的节奏? 不。 它只在A#a这个方法内有用,不会污染到全局,但是你在碰到类似情况的时候,一定要注意。当然,在A的子类,也会被传下去,除非a方法被重写。
还有个值得说明的地方,就是,using的模块,不会被挂到继承树(祖先树/ancestors tree)上:
可以看到, NumberQuery并没有被挂到祖先树上。
到此,关于“Ruby2.1中Refinements特性有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。