Ruby meta_prgramming alias_method_chain ()

Unknow user · October 18, 2012 · Last by xiaobingzai replied at October 20, 2012 · 2727 hits
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对象而已。 另外强烈建议楼主下次发帖时格式化代码,没格式化的代码看着太难受了。

Unknow user #1 October 18, 2012

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

Unknow user #2 October 18, 2012

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

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

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

You need to Sign in before reply, if you don't have an account, please Sign up first.