Ruby Digest(2)

Ruby Digest(2)

ruby的基本rule都是普遍试用的,不像有些语言总是有些exception。所以只要知道了ruby基本规则,就可以自行推倒各种复杂的规则。

方法method

ruby为动态类型检查,只有run的时候会报错。

动态方法 Dynamic Method

在执行过程中生成一下方法(原本方法名都是常量,但动态生成时,方法名就可以是变量了)

class MyClass
  def my_method(my_arg)
    my_arg * 2
  end
obj = MyClass.new
obj.my_method(3)

obj.send(:my_method3#动态调用,:my_method可以为变量
  • obj.send(method_name)称为动态分发,因为method在运行时才确定
  • YAML K/V方式存储配置文件的格式(or 序列化格式)
  • 只调用以test开头的方法,有时被称为 模式分发(Pattern Dispath)

动态定义方法 Defining Methods Dynamically

  • Module#define_method()
class MyClass
  define_method :my_method do |my_arg|
    my_arg * 3
  end

obj = MyClass.new
obj.send(:my_method3) # => 9
  • 显然上面的 :my_method 可更换为变量,也就达到了动态定义方法名的目的
class MyClass
  ['a', 'b', 'c'].each do |name|
    define_method (name) {
      name * 3
    }
  end
end

这样就定义了MyClass#a MyClass#b Myclass#c

method_missing()方法

又称 幽灵方法(Ghost Method) 因为 MyClass#method_name其实不存在

class Lawyer; end
nick = Lawyer.new
nick.talk_simple
=> NoMethodError: undefined method 'talk simple'
  • 实际上调用不存在的方法 会进入 method_missing方法
  • method_missing为一个私有方法
  • nick.send :method_missing, :my_method可调用私有方法
class Lawyer
  def method_missing(method, *args)
    puts "You called: #{method}(#{args.join(', ')})"
    puts "(You also passed it a block)" if block_given?
  end
end

bob = Lawyer.new
bob.talk_simple('a', 'b') do
  # a block
end

=> You called: talk_simple(a, b)
   (You also passed it a block)

这样就可以动态定义一个方法了

  • method_missing可以很容易做Proxy, class A 里有个class B的实例,当用户调 a.b_method 可以自动转发到 b.b_method
  • delegate 库帮我们做了动态代理的method_missing的撰写
  • 幽灵方法找不到对应的方法, 为了避免这个;可以复写respond_to? 申明method_missing中实现了某个方法
  • method_missing中尽量不调用别的方法,否则容易进入死循环
  • best-practice: 在method_missing中制定要处理的未知Method名称集合
  • 父类占用了某个函数名,就不能进入method_missing了,此时最好使用白板类,即没有任何方法的基类
  • ruby1.9起 BasicObject的子类即为白板类

动态方法 VS 幽灵方法

  • 动态方法实际定义了方法,因此占用了空间
  • 幽灵方法实际并没定义方法,因此不占用空间,但是比较慢;
  • 一个合理的方案是,当一个幽灵方法第一次被调用时,动态生成该方法;
  • 这样既节约了内存,又加快了函数调用速度;
  • 该方案称为 lazy loading, 仅在使用时加载;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值