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.
The plan is to extend Numeric
with ahumanize
method that returns a human-friendly string when called on a number. After looking at the source of Number::Bytes::Human (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 floor
rather than ceil
for the default rounding function.
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:
def humanize(params = {})
params = {:block => 1024, :r_func => lambda }.merge params
# yada yada
end
Ideally, I would like to let the user pass a function as the value of params[:r_func]
, but I can't figure out how to validate that it's either ceil
or floor
. Because I can't get a handle on this, I've ended up doing the following, which feels pretty clumsy:
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
If anyone knows a trick for peeking at the method that a Ruby lamda contains, I would love to hear it. (I'm also happy to hear any other design advice.) Thanks.