0

I am trying to refactor my code (before it was a bunch of if/else-if statements) using some Ruby magic. However, when I try to use code blocks as my value in a hash, I get the following error:

syntax error, unexpected '}', expecting tASSOC :restaurant => { Cuisine.all },

This same error repeats for the next line and the line after (:hotel and :attraction).

What am I doing incorrectly here?

def moderation_categories(klass) 
  klass_map = {
    :restaurant => { Cuisine.all },
    :hotel      => { Category.where(place_type: "Hotel") },
    :attraction => { Category.where(place_type: "Attraction") }
  }
  list = []
  klass_map[klass.to_sym].call.each { |c| list << c.name }

  list.sort
end
Huy
  • 10,806
  • 13
  • 55
  • 99
  • 1
    This is unrelated to your question, but the last three lines of your method could be simplified to one: `klass_map[klass.to_sym].call.map {|c| c.name }.sort`. The `map` method lets you avoid creating and appending that intermediate `list` manually. – Scott Olson Oct 24 '12 at 23:17
  • @ScottOlson Awesome, thanks. So much Ruby magic :) – Huy Oct 24 '12 at 23:19
  • 1
    No problem. Ruby gets even more magic than that, too! Since `{|x| x.method }` turns out to be a common block, there's an even shorter form: `klass_map[klass.to_sym].call.map(&:name).sort`. An explanation for that syntax can be found here: http://stackoverflow.com/q/1961030/1535283 – Scott Olson Oct 24 '12 at 23:23

1 Answers1

4

A block does not just stand as a lambda (code block). You must specify it to be a lambda or a Proc.

  klass_map = {
    :restaurant => lambda{ Cuisine.all },
    :hotel      => lambda{ Category.where(place_type: "Hotel") },
    :attraction => lambda{ Category.where(place_type: "Attraction") }
  }
SwiftMango
  • 15,092
  • 13
  • 71
  • 136