Руби и если заявления - PullRequest
       10

Руби и если заявления

1 голос
/ 06 марта 2012

Позвольте мне предварить это словами, что я новичок в Ruby.

Я пытался сделать что-то вроде этого:

raise NoSuchStrategyError unless ((player1[1].downcase && player2[1].downcase) == ( "p" || "r" || "s"))

Однако это не сработало как задумано Это только признал, если первый аргумент был "р". Если это был «r» или «s», то выдается ошибка. Я должен был написать это так, чтобы это работало:

raise NoSuchStrategyError unless player1[1].downcase == "p" or player1[1].downcase == "s" or player1[1].downcase == "r"
raise NoSuchStrategyError unless player2[1].downcase == "p" or player2[1].downcase == "s" or player2[1].downcase == "r"

Есть ли лучший способ сделать это сокращение?

Ответы [ 4 ]

2 голосов
/ 06 марта 2012

Вы могли бы просто сделать:

"pry".include?(player1[1].downcase)

Реальная проблема с вашим кодом в том, как вы его структурируете. Когда вы обнаруживаете, что объявляете переменные, такие как player1 и player2, затем пишете кучу повторяющегося кода для работы с этими переменными, обычно это подсказка, что вам нужно объявить класс Player:

 class Player

   def initialize(name)
     @name = name
     @strategy = "goofy"
   end

   def valid_strategy?
     return "pry".include?(@strategy)
   end

 end

Тогда ваша строка выглядит так:

raise NoSuchStrategyError unless @player.valid_strategy?
2 голосов
/ 06 марта 2012

Это потому, что || возвращает первый правдивый аргумент.В этом случае, поскольку "p" является правдой, ("p" || "r" || "s") всегда возвращает "p".Зная это, ваше первое утверждение может быть эквивалентно переписано как:

raise NoSuchStrategyError unless ((player1[1].downcase && player2[1].downcase) == "p"

Как намекал Блендер в своем комментарии о Python, вы можете сделать:

raise NoSuchStrategyError unless ['p', 'r', 'y'].include?(player1[1].downcase) && ['p', 'r', 'y'].include?(player2[1].downcase)

или более кратко:

raise NoSuchStrategyError unless [player1[1].downcase, player2[1].downcase].all? { |c| %w[p r s].include? c }

Кроме того, будьте осторожны при использовании and & or в Ruby, они отличаются от && & ||.Вы можете (и должны) узнать больше о разнице .

1 голос
/ 06 марта 2012

В вашем подходе ('p' || 'r' || 's') всегда возвращает 'p', так как в Ruby кроме nil и false все равно true, включая 0. Поэтому, кроме 'p', ваш подход терпит неудачу.


Попробуйте вместо Array#include? метод.

plays = ['p', 'r', 's']

raise NoSuchStrategyError unless ( plays.include?(player1[1].downcase) && 
                                   plays.include?(player2[1].downcase) 
                                 )
1 голос
/ 06 марта 2012

Вы можете упростить это так:

raise NoSuchStrategyError unless (%w(a b c).include?(player1[1].downcase) && %w(a b c).include?(player2[1].downcase))

Редактировать

Еще более простое решение:

raise NoSuchStrategyError if ("pry"[player1[1].downcase] || "pry"[player2[1].downcase])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...