noMAD
noMAD

Reputation: 7844

ruby injecting methods as parameters

So am trying to write functional ruby and for this purpose need to inject lambdas where ever required. But this is turning out to be not so elegant and useful. Example:

def this_is_a_test(arg1, fn_one = self.default_fn_one, fn_two = self.default_fn_two)
  #Something here
end

There are two disadvantages about this:

  1. If I need to inject more methods, the arity becomes too big
  2. If I want to only inject fn_two and use default for fn_one its not possible

So I tried this approach (picked up the idea from rails):

def this_is_a_test(arg1, options = {})
  opts = {
    fn_one: self.default_fn_one,
    fn_two: self.default_fn_two
  }.merge(options)

#Something here

end

This does take care of those two cases but I wanted to know if this is the best approach? Is there a way to do this without the options hash?

Upvotes: 1

Views: 153

Answers (1)

Denis de Bernardy
Denis de Bernardy

Reputation: 78413

I think you want to use method and explicit proc or lambda constructs. In Ruby 2.0, your opts hash can also be removed entirely by using named parameters. (Amend your opts hash approach if you want to target earlier versions of Ruby too.)

def this_is_a_test(arg1,
                   fn_one: method(:default_fn_one),
                   fn_two: method(:default_fn_two))
  puts fn_one.call
  puts fn_two.call
  yield if block_given? # allow to pass an optional block too
end

this_is_a_test(:foo, fn_one: lambda { :bar } do
  puts :baz
end

(untested, but should put you in the right direction.)

Upvotes: 1

Related Questions