alias:是关键词(执行参数的顺序是新旧交替,就是依次是新方法和旧方法)

alias_method:是module中的实例方法

remove_method:取消child中的方法定义,保留parent中的方法定义

undef_method:取消child和parent中的方法定义

alias和alias_method的应用场景:有一个不能直接修改的方法,因为这个方法在库中,希望这个方法包装额外的特性,所有的客户端都能自动获取这个额外特性。

#使用关键字alias:
class MyClass
  def my_method
    puts "this is my method"
  end

  alias :m :my_method  #关键字alias,不用加逗号
end

obj = MyClass.new
obj.my_method  #=> this is my method
obj.m  #=> this is my method
#使用alias_method方法
class MyClass
  alias_method :m2, :m
end

obj.m2 #=> this is my method
#alias和alias_method区别
1.alias是关键词,alias_method是Module的方法
2.alias在顶级作用域是可以用的,alias_method在顶级作用域中不可用

alias_method :demo, :display  #error
alias :demo, :display #success

#但是打开Object是可以使用alias_method,这是和上面的矛盾的地方
#Object.ancestors #[Object, PP::ObjectMixin, Kernel, BasicObject],其中PP::ObjectMixin是module,其包括alias_method方法
class Object
  alias_method :demo, :display #success
end

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

#环绕别名的一般使用方式
class String
  alias :real_length :length

  def length
    real_length > 5 ? "long" : "short"
  end
end

"war and peace".length #=> long
"war and peace".real_length #=> 13
#refine中结合super来实现环绕别名
module StringRefine
  refine String do 
    def length
      super > 6 ? 'long' :'short'
    end
  end
end

using StringRefine
"hello".length #'short'
"xxxxxwe".length #'long'

定义环绕别名的时候需要遵循下面的两个要求:1.设置别名链时,确保别名是独一无二的。2.必要时考虑提供一个撤销别名链的方法。代码参考如下:

#代码示例,保证别名链唯一,同时最后调用撤销别名链的方法
module LogMethod
  def log_method(method)
    orig = "#{method}_without_logging".to_sym

    if instance_methods.include?(orig)
      raise(NameError, "#{orig} isn't a unique name")
    end

    alias_method(orig, method)

    define_method(method) do |*args, &block|
      $stdout.puts("calling method '#{method}'")
      result = send(orig, *args, &block)
      $stdout.puts("'#{method}' returned #{result.inspect}")
      result
    end
  end

  def unlog_method(method)
    orig = "#{method}_without_logging".to_sym

    if !instance_methods.include?(orig)
      raise(NameError, "was #{orig} already removed?")
    end

    remove_method method
    alias_method method, orig
    remove_method(orig)
  end
end

Array.extend LogMethod
Array.log_method :first
p [1,2,3].first
#calling method 'first'
#'first' returned 1
#1
p [1,2,3].first_without_logging
#1
Array.unlog_method :first
p [1,2,3].first
#1
p [1,2,3].first_without_logging
#error

results matching ""

    No results matching ""