Ruby和if语句

时间:2012-03-06 07:19:58

标签: ruby operators

让我先说明我是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"

有没有更好的方法来做这个速记?

4 个答案:

答案 0 :(得分:2)

这是因为||返回的第一个参数是真实的。在这种情况下,由于"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&时要小心在Ruby中or,它们与&&& ||。你可以(而且应该)read more about the difference

答案 1 :(得分: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?

答案 2 :(得分: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])

答案 3 :(得分:1)

在您的方法中,('p' || 'r' || 's')始终返回'p',因为除了nilfalse之外,所有内容都是true,包括0.因此,除了'p'之外,方法失败。


请改用Array#include?方法。

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

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