代码之家  ›  专栏  ›  技术社区  ›  Telemachus MrJames

如何在Ruby中验证传递给方法的函数?

  •  1
  • Telemachus MrJames  · 技术社区  · 16 年前

    Numeric humanize Number::Bytes::Human (我非常喜欢这个Perl模块),我决定向该方法添加两个选项:一个使用1000字节块,一个使用 floor ceil 对于默认的舍入功能。

    为了获得最大的灵活性,该方法的定义使用哈希作为参数,以便用户可以更改一个或两个选项。如果没有传递参数,则使用默认哈希。这给了我这样的东西:

    def humanize(params = {})
      params = {:block => 1024, :r_func => lambda }.merge params
      # yada yada
    end
    

    理想情况下,我想让用户传递一个函数作为 params[:r_func] (用熟石膏、木板等)装天花板 。因为我无法处理这件事,我最终做了以下事情,感觉很笨拙:

      def humanize(params = {})
        params = {:block => 1024, :r_func => 'ceil' }.merge params
        if params[:r_func].eql? 'ceil'
          params[:r_func] = lambda { |x| x.ceil }
        elsif params[:r_func].eql? 'floor'
          params[:r_func] = lambda { |x| x.floor }
        else 
          raise BadRound, "Rounding method must be 'ceil' or 'floor'."
        end
        # blah blah blah
      end
    

    如果有人知道偷看Ruby lambda包含的方法的诀窍,我很想听听。(我也很乐意听到任何其他设计建议。)谢谢。

    3 回复  |  直到 13 年前
        1
  •  7
  •   Avdi    16 年前

    如果你对允许用户传递的方法如此严格(你知道有 other rounding schemes

    :ceiling :floor 更灵活的设计是允许该方法取一个接收单个参数的块,数字四舍五入。然后,用户可以使用他们喜欢的任何舍入算法,包括自定义算法。

    顺便说一句, Numeric#humanize 属于猴痘病毒的一类,其名称如此流行,以至于除了一个小型的个人项目外,你很可能会在任何事情上遇到名称空间冲突(以及由此产生的微妙错误)。

        2
  •  3
  •   Chuck    16 年前

    raise BadRound, "Rounding method must be :ceil or :floor." unless [:ceil, :floor].include? params[:r_func]
    op = lambda {|x| x.send params[:r_func]}
    # blah blah blah
    
        3
  •  2
  •   Yuliy    16 年前

    为什么他们传递函数指针而不是布尔值?这样就避免了必须验证函数的问题。