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

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

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

    计划是延长 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    15 年前

    如果你对允许用户传递的方法如此苛刻,那么没有理由让用户传递方法(你知道有) other rounding schemes

    如果要将用户限制在天花板和地板上,只需允许他们通过符号即可 :ceiling :floor 在里面一个更灵活的设计是允许该方法采用一个块,该块接收一个参数,即要舍入的数字。然后用户可以使用他们喜欢的任何舍入算法,包括自定义算法。

    顺便说一句 Numeric#humanize 属于monkeypatches这一类,它的名字非常流行,以至于除了一个小型的个人项目之外,您很可能会在任何事情中遇到名称空间冲突(以及由此产生的微妙错误)。

        2
  •  3
  •   Chuck    15 年前

    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    15 年前

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