2012-03-06 2 views
1

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

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

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

Однако она не работает, как предполагалось. Он признал только, что первым аргументом был «p». Если это была «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" 

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

+0

В Python вы делаете 'if foo in ['a', 'b', 'c']'.Мне было бы интересно узнать, сможет ли Ruby это сделать. – Blender

+0

@Blender Действительно есть, но только обратный через ['Enumerable # include?'] (Http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-include-3F): '['a', 'b', 'c']. include? Foo'. (Хотя, строго говоря, '' Array' переопределяет 'include?'] (Http://ruby-doc.org/core-1.9.3/Array.html#method-i-include-3F).) –

+0

Я понимаю, что я немного поздно, но я не думаю, что смогу идти в ногу со всеми моими обязанностями. Я пытаюсь работать через это, как только я получаю время – Calihan

ответ

2

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

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

Как Blender намекают в своем комментарии о 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, они отличаются от && & ||. Вы можете (и должны) read more about the difference.

1

Вы могли бы упростить это так:

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]) 
+0

Я думаю, что, несмотря на '' pry '[player1 [1] .downcase] ', будучи чудесно кратким, некоторые из намерений того, что делается, теряются при использовании' 'pry'' в качестве замены набора одиночных персонажи. –

1

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


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

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

raise NoSuchStrategyError unless (plays.include?(player1[1].downcase) && 
            plays.include?(player2[1].downcase) 
           ) 
2

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

"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? 
+1

или даже короче, '' pry '[player1 [1] .downcase] ' – pduersteler

Смежные вопросы