Ruby meta_prgramming alias_method_chain ()

匿名 · 2012年10月18日 · 最后由 xiaobingzai 回复于 2012年10月20日 · 2719 次阅读
class MyClass
  def greet_with_log
    puts "Calling method..."
    greet_without_log
    puts "...Method called"
  end
  alias_method :greet_without_log, :greet
  alias_method :greet, :greet_with_log
end

MyClass.new.greet ⇒ Calling method... Hello! ...Method called 没看懂,不懂,不理解。。。

class MyClass
  def greet_with_log
    puts "Calling method..."
    greet_without_log
    puts "...Method called"
  end

  def great
    puts 'Hello!'
  end

  alias_method :greet_without_log, :greet
  alias_method :greet, :greet_with_log
end

MyClass.new.greet     
  
  Calling method...
  Hello!
  ...Method called

alias_method :greet_without_log, :greet这句代码使得greet_without_log等同于greet;

alias_method :greet, :greet_with_log这句则又使得greet等同于了greet_with_log;

所以这时候你再调用greet时就相当于调用了greet_with_log了,至于在greet_with_log内部由于greet_without_log此时是等价于之前的greet的,所以调用时输出的是'Hello'

这里需要说明的一个问题是:

调用alias或者alias_method的实质其实是将原有的Method对象(greet变量所指向的)复制了一份,生成一个匿名的Method对象,然后将该对象赋值个变量greet_without_log; 简单的说就是在ruby中一切皆为对象,方法也不例外,方法名实质上是一个变量,它的值就是对应的Method对象。 先看下面的代码:

greet = 1
greet_with_log = 2
greet_without_log = greet
greet = greet_with_log

p greet     #=>  2
p greet_without_log   #=>  1

可以说从实质上来时上面的代码和你给出的代码是没有区别的,仅仅是吧上面的数字换成Method对象而已。 另外强烈建议楼主下次发帖时格式化代码,没格式化的代码看着太难受了。

匿名 #2 2012年10月18日

#1 楼 @zzhattzzh 我确实格式化代码了,两个空格那样对齐的,发贴之后就变成这样了,很是郁闷

匿名 #3 2012年10月18日

#1 楼 @zzhattzzh 好吧,我用了 code /code。。。

#1 楼 @zzhattzzh 这句话: 调用 alias 或者 alias_method 的实质其实是将原有的 Method 对象(greet 变量所指向的)复制了一份,生成一个匿名的 Method 对象,然后将该对象赋值个变量 greet_without_log;

为啥不是复制了对象的引用给 greet_without_log,好象没有必要重新复制一份 Method 对象。

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