zoukankan      html  css  js  c++  java
  • 一个使用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
    
  • 相关阅读:
    简单的纯css菜单
    提高 web 应用性能之 JavaScript 性能调优(转)
    从拖延者到行动派的10个秘诀(转)
    程序员,你应该知道(转)
    幽默的经济学+组织领导学
    [SQL基础]统计信息解释
    演讲集合
    最隐晦的程序设计指引(转)
    windows 7 "unmountable boot volume" 解决方法
    kafka与springboot集成2
  • 原文地址:https://www.cnblogs.com/leaf526/p/3496284.html
Copyright © 2011-2022 走看看