title: How can I validate a function passed to a method in Ruby?
body: <p>I'm writing a library to humanize bytes in Ruby (e.g. to turn the byte count 1025 into the string 1.1K), and I'm stuck on one element of the design. </p>
  
  <p>The plan is to extend <code>Numeric</code> with a<code>humanize</code> method that returns a human-friendly string when called on a number. After looking at the source of <a href="http://search.cpan.org/perldoc?Number::Bytes::Human" rel="nofollow noreferrer">Number::Bytes::Human</a> (a Perl module that I like a lot for this), I decided to add two options to the method: one to use 1000 byte blocks and one to use <code>floor</code> rather than <code>ceil</code> for the default rounding function. </p>
  
  <p>In order to be maximally flexible, the method's definition uses a hash for the parameters, so that users can change one or both of the options. If no parameters are passed, a default hash is used. That gives me something like this:</p>
  
  <pre><code>def humanize(params = {})
    params = {:block =&gt; 1024, :r_func =&gt; lambda }.merge params
    # yada yada
  end
  </code></pre>
  
  <p>Ideally, I would like to let the user pass a function as the value of <code>params[:r_func]</code>, but I can't figure out how to validate that it's either <code>ceil</code> or <code>floor</code>. Because I can't get a handle on this, I've ended up doing the following, which feels pretty clumsy:</p>
  
  <pre><code>  def humanize(params = {})
      params = {:block =&gt; 1024, :r_func =&gt; '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
  </code></pre>
  
  <p>If anyone knows a trick for peeking at the method that a Ruby lambda contains, I would love to hear it. (I'm also happy to hear any other design advice.) Thanks.</p>