一个使用method_missing()容易引发的bug

class Roulette
    def method_missing(name,*args)
        person = name.to_s.capitalize
        3.times do
            number = rand(10) + 1
            puts "#{number} = ..."
        end
        puts "#{person} got a #{number}"
    end
end
number_of = Roulette.new
puts number_of.bob
puts number_of.frank

      Ruby元编程里搬过来的例子.这个程序里,number是定义在传给times方法的那个块中,在第八行引用的时候,已经超出了它的作用域.Ruby无从得知此处的number应该是一个变量.默认情况下,它把number当成一个在self上省略了括号的方法调用.
  通常情况下,会抛出一个明显的NoMethodError错误,但是在这个程序里,已经自己定义了一个method_missing()方法,所以number()方法的调用最终都会来到这里,因此会陷入死循环,直到调用堆栈溢出为止.
  这是使用幽灵方法的时候会经常出现的问题:由于调用未定义的方法会导致调用method_missing()方法,对象可能会因此接受一个直接的错误方法调用(不如输错了方法名).
  为了避免这样的困扰,应该仅在必要时才使用幽灵方法.碰到不知道如何处理的方法时,记得回到Kernel#method_missing()方法.

  修改后的方法:

class Roulette
    def method_missing(name,*args)
        person = name.to_s.capitalize
        super unless %w[Bob Frank Bill].include?person
        number = 0
        3.times do
            number = rand(10) + 1
            puts "#{number} = ..."
        end
        puts "#{person} got a #{number}"
    end
end
number_of = Roulette.new
puts number_of.bob
puts number_of.frank

 

转载于:https://www.cnblogs.com/leaf526/p/3496284.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值