John Carter John Carter - 2 months ago 13
Ruby Question

Ruby - How do I shorten my method

I have a hash here:

VALID_CHOICES = {
'r' => 'rock',
'p' => 'paper',
'sc' => 'scissors',
'l' => 'lizard',
'sp' => 'spock'
}


And a method which basically compares here:

def win?(first, second)
(first == 'sc' && second == 'p') ||
(first == 'p' && second == 'r') ||
(first == 'r' && second == 'l') ||
(first == 'l' && second == 'sp') ||
(first == 'sp' && second == 'sc') ||
(first == 'sc' && second == 'l') ||
(first == 'l' && second == 'p') ||
(first == 'p' && second == 'sp') ||
(first == 'sp' && second == 'r') ||
(first == 'r' && second == 'sc')
end


How can I rewrite my method in very short concise code that means exactly the same thing? Any idea? Is it possible to do it using hashes?

Answer

You should define clear rules for what each token can win:

WINS = {
  'r' => %w{l sc},
  'p' => %w{r sp},  
  'sc' => %w{p l},
  'l' => %w{p sp},
  'sp' => %w{r sc}
}

Now you can determine wins using a simple lookup:

def win?(first, second)
  WINS[first].include?(second)
end

While there may be several 'clever' ways to avoid an explicit structure like WINS, explicit rules are much more understandable - and therefore, more maintainable. Conciseness in code is considered a positive attribute where it improves the readability of the code. Conciseness to the extreme that causes the code to be difficult to understand is not something to strive for.

Comments