peter
peter

Reputation: 42192

evading the use of if statements: shortening the code

I watched the video at https://gorails.com/blog/refactoring-if-statements but was looking for a more concise way of evading the use of multiple if or case statements. The following works

            def process(input)
                commands = {
                    :q => Proc.new { puts "Goodbye" }, 
                    :tweet => Proc.new { puts "tweeting" }, 
                    :dm => Proc.new { puts "direct messaging"}, 
                    :help => Proc.new { puts "helping"}
                }
                commands[input.to_sym].call
            end

            process "tweet"

But how could i further shorten this ? I tried the following

            def process(input)
                commands = {
                    :q => { puts "Goodbye" }, 
                    :tweet => { puts "tweeting" }, 
                    :dm => { puts "direct messaging"}, 
                    :help => { puts "helping"}
                }
                commands[input.to_sym].to_proc.call
            end

            process "tweet"

but then i get the error

            # syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('
            #       :q => { puts "Goodbye" }, 
            #                     ^

Any suggestions please ?

Upvotes: 0

Views: 67

Answers (3)

Roman Kiselenko
Roman Kiselenko

Reputation: 44370

Use Kernel#proc:

Equivalent to Proc.new

def process(input)
  commands = {
    :q => proc { puts "Goodbye" }, 
    :tweet => proc { puts "tweeting" }, 
    :dm => proc { puts "direct messaging"}, 
    :help => proc { puts "helping"}
  }[input.to_sym].call
end

Upvotes: 2

Uri Agassi
Uri Agassi

Reputation: 37409

Use the lambda syntax

def process(input)
  commands = {
    :q => ->{ puts "Goodbye" }, 
    :tweet => ->{ puts "tweeting" }, 
    :dm => ->{ puts "direct messaging"}, 
    :help => ->{ puts "helping"}
  }
  commands[input.to_sym].to_proc.call
end

process "tweet"

Using the new Hash syntax can shorten this further:

def process(input)
  {
    q: ->{ puts "Goodbye" }, 
    tweet: ->{ puts "tweeting" }, 
    dm: ->{ puts "direct messaging"}, 
    help: ->{ puts "helping"}
  }[input.to_sym].call
end

process "tweet"

Upvotes: 3

Kostas Rousis
Kostas Rousis

Reputation: 6068

I am not sure whether what you suggest or I will suggest here improves the elegance or the readability of the code under question but you could shorten it even further by using the hash accessor pattern as in:

def process(input)
  commands = {
    :q => Proc.new { puts "Goodbye" }, 
    :tweet => Proc.new { puts "tweeting" }, 
    :dm => Proc.new { puts "direct messaging"}, 
    :help => Proc.new { puts "helping"}
  }[input.to_sym].call
end

Upvotes: 1

Related Questions