让我先说明我是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 :(得分: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',因为除了nil
和false
之外,所有内容都是true
,包括0.因此,除了'p'之外,方法失败。
请改用Array#include?
方法。
plays = ['p', 'r', 's']
raise NoSuchStrategyError unless ( plays.include?(player1[1].downcase) &&
plays.include?(player2[1].downcase)
)