Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Searching through a hash in ruby with values that are methods

I'm having a problem searching through a hash where my values are methods. I just wan't to run the method where plan_type matches the key.

def method(plan_type, plan, user)
  {
    foo: plan_is_foo(plan, user),
    bar: plan_is_bar(plan, user),
    waa: plan_is_waa(plan, user),
    har: plan_is_har(user)
  }[plan_type]
end

Currently if I pass in "bar" as the plan_type, every method will be run, how can I only run just the plan_is_bar method?

like image 681
Jay Avatar asked Jul 03 '15 15:07

Jay


2 Answers

what about this variant?

def method(plan_type, plan, user)
  {
    foo: -> { plan_is_foo(plan, user) },
    bar: -> { plan_is_bar(plan, user) },
    waa: -> { plan_is_waa(plan, user) },
    har: -> { plan_is_har(user) }
  }[plan_type].call
end

Using lambdas or procs is a good way to make things lazy, because they are executed only when they receive method call

Because of this you can use ->(lambda literal) as lightweight wrapper around probably heavy calculations and call it only when you needed.

like image 186
Mihail Davydenkov Avatar answered Nov 03 '22 00:11

Mihail Davydenkov


A very straightforward solution:

Code

def method(plan_type, plan=nil, user)
  m =
  case plan_type
  when "foo" then :plan_is_foo
  when "bar" then :plan_is_bar
  when "waa" then :plan_is_waa
  when "har" then :plan_is_har
  else nil
  end

  raise ArgumentError, "No method #{plan_type}" if m.nil?
  (m==:plan_is_har) ? send(m, user) : send(m, plan, user)
end

You could of course use a hash instead of a case statement.

Example

def plan_is_foo plan, user
  "foo's idea is to #{plan} #{user}"
end

def plan_is_bar plan, user
  "bar's idea is to #{plan} #{user}"
end

def plan_is_waa plan, user
  "waa's idea is to #{plan} #{user}"
end

def plan_is_har user
  "har is besotted with #{user}"
end

method "foo", "marry", "Jane"
  #=> "foo's idea is to marry Jane"

method "bar", "avoid", "Trixi at all costs"
  #=> "bar's idea is to avoid Trixi at all costs" 

method "waa", "double-cross", "Billy-Bob"
  #=> "waa's idea is to double-cross Billy-Bob"

method "har", "Willamina"
  #=> "har is besotted with Willamina"

method "baz", "Huh?"
  #=> ArgumentError: No method baz 
like image 33
Cary Swoveland Avatar answered Nov 03 '22 00:11

Cary Swoveland