Ruby 《Ruby 元编程》读书笔记 (十一)

lazybios · September 18, 2015 · Last by lazybios replied at June 26, 2016 · 2543 hits

博客地址 :《Ruby 元编程》读书笔记 (十一)

相关文章:

《Ruby 元编程》读书笔记 (一) 《Ruby 元编程》读书笔记 (二) 《Ruby 元编程》读书笔记 (三) 《Ruby 元编程》读书笔记 (四) 《Ruby 元编程》读书笔记 (五) 《Ruby 元编程》读书笔记 (六) 《Ruby 元编程》读书笔记 (七) 《Ruby 元编程》读书笔记 (八) 《Ruby 元编程》读书笔记 (九) 《Ruby 元编程》读书笔记 (十)

传神的头图↓↓↓

Ruby元编程

方法包装器(Method Wrapper)

方法包装器一般适合于,处理一些你不能直接触碰到的方法,或者需要给某个方法进行一些预处理工作,这个概念有点类似与 Python 中的装饰器

方法别名

Ruby中使用Module#alias_method方法和alias关键字为方法取别名。

示例代码
class MyClass
    def my_method
         my_method()
    end
    alias_method :m, :my_method
end

obj = MyClass.new
obj.my_method    #=> “my_method()”
obj.m   #=> “my_method()”

需要注意的是,在顶级作用域中(main)中只能使用alias关键字来命名别名,因为在那里调用不到Module#alias_method方法

此外这里,还需要指出一点关于方法重定义的理解误区,一般我们认为方法一旦被重定义了,就找不回原来的方法了,其实在 Ruby 中的重定义只是,对方法名与方法实体绑定的一种重新绑定,如果被重新定义的方法体还有一个其它别名,那么一样还是可以访问到老方法的。

有了上面这个理解,我们来看环绕别名这个概念。

环绕别名

经过下面三个步骤可以实现环绕别名

  1. 给方法定义一个别名
  2. 重定义这个方法
  3. 在新的方法中调用老的方法

上面三步后,即可以保留老方法 (第一步),同时又为原方法增加了新功能。但其本质上没有改变调用之间的函数名称依赖,是一种名副其实的“新瓶装老酒”的取巧办法。

不过环绕别名也有缺点,就是它污染了类的命名空间,添加了额外的方法名。不过这一点其实可以通过 Ruby 中的 private 关键字把旧方法限定为私有方法。(Ruby 中的 public 和 private 实际上针对的是方法名,而非方法本身,言外之意为 private 方法取个别名,也可以把私有方法暴露出来)

最后要注意的是不要尝试 load 两次环绕别名的实现代码,否则得到的执行结果就不是你预期中的了,不信你可以试着连续走两遍上面的 3 个步骤。

细化

前面提到的细化,也可以作为一种方法包装器,在细化的方法中调用 super 方法,可以调用会细化之前的方法。此外细化相比起环绕别名,细化的作用范围是文件末尾,而环绕别名则是作用在全局。

module StringRefinement
  refine String do
    def length
      super > 5 ? 'long' : 'short'
    end
  end
end

using StringRefinement

puts "War and Peace".length  #=> “long”

下包含包装器 (Module#prepend)

在介绍祖先链的部分有涉及过 include 与 prepend 两个方法,前者是将模块插入到当前类的上方,后者是插入到下方,而下方的位置,正好是方法查找时优先查找的位置,利用这一优势,可以覆写当前类的同名方法,同时通过 super 关键字还可以调用到该类中的原始方法

module ExplicitString
    def length
        super > 5 ? long : short
    end
end

String.class_eval do
    prepend ExplicitString
end

puts "War and Peace".length  #=> “long”

-待续-

=============== 最后贴一下自己的公众账号

可以十日不将军,不可一日不拱卒,日拱一卒 (rigongyizu365)

lazybios in 《Ruby 元编程》读书笔记 (十二) mention this topic. 26 Jun 10:50
lazybios in 《Ruby 元编程》读书笔记 (十三) mention this topic. 26 Jun 10:50
lazybios in 《Ruby 元编程》读书笔记 (十四) mention this topic. 26 Jun 10:50
lazybios in 《Ruby 元编程》读书笔记 (十五) mention this topic. 26 Jun 10:50
You need to Sign in before reply, if you don't have an account, please Sign up first.