提高条件中的异常

时间:2013-10-23 04:44:34

标签: ruby exception

我正在尝试创建一个石头剪刀程序,到目前为止这个代码有效但参数没有被抛出,我该如何解决这个问题?

class RockPaperScissors

  # Exceptions this class can raise:
  class NoSuchStrategyError < StandardError ; end

  def self.winner(player1, player2)
    p1c = player1.last.downcase
    p2c = player2.last.downcase
    p1wins = false

    case p1c
      when "p"
        if (p2c == "p" or p2c == "r")
          p1wins = true
        end 
      when "s"
        if (p2c == "p" or p2c == "s")
          p1wins = true
        end
      when "r"
        if (p2c == "r" or p2c == "s")
          p1wins = true
        end
      else
        raise NoSuchStrategyError, "Strategy must be one of R,P,S" 
    end
  end

为什么不抛出错误? 编辑*

这用于使用rspec测试代码,因为你可以看到一个带有Name的数组,后跟他们在capse中选择的内容

before(:each) do
@rock = ['Armando','R'] ; @paper = ['Dave','P'] ; @scissors = ['Sam','S']
end
describe 'game' do
it 'rock breaks scissors' do
  RockPaperScissors.winner(@rock, @scissors).should == @rock
end
it 'scissors cut paper' do
  RockPaperScissors.winner(@paper, @scissors).should == @scissors
end
it 'paper covers rock' do
  RockPaperScissors.winner(@rock, @paper).should == @paper
end
it 'first player wins if both use same strategy' do
  RockPaperScissors.winner(@scissors, ['Dave','S']).should == @scissors
end
end
it "should raise NoSuchStrategyError if strategy isn't R, P, or S" do
lambda { RockPaperScissors.winner(@rock, ['Dave', 'w']) }.
  should raise_error(RockPaperScissors::NoSuchStrategyError,
  "Strategy must be one of R,P,S")
end

1 个答案:

答案 0 :(得分:1)

编辑:根据您新提供的测试代码,问题是您只测试代码中第一个播放器的策略。但是,在测试代码中,第一个玩家(@rock)有一个有效的策略;这是第二个拥有无效策略的玩家。请参阅我的代码,了解一种测试方法。


当我将缺少的end添加到您的代码中时,它适用于我:

Player = Struct.new(:last)
RockPaperScissors.winner(
  Player.new("cats"),
  Player.new("dogs")
)
#=> /Users/phrogz/Desktop/tmp.rb:24:in `winner': Strategy must be one of R,P,S (RockPaperScissors::NoSuchStrategyError)

请注意,我会像这样重写您的方法:

class RockPaperScissors
  class NoSuchStrategyError < StandardError ; end
  LEGAL_MOVES = %w[r p s]
  def self.winner(player1, player2)
    p1c = player1.last.downcase
    p2c = player2.last.downcase
    unless LEGAL_MOVES.include?(p1c) && LEGAL_MOVES.include?(p2c)
      raise NoSuchStrategyError, "Strategy must be one of R,P,S"
    end
    if p1c!=p2c then
      case p1c
        when "r" then p2c=="s" ? player1 : player2
        when "p" then p2c=="r" ? player1 : player2
        when "s" then p2c=="p" ? player1 : player2
      end
    end
  end
end

这会在无效移动时引发错误,如果两个玩家并列,则返回nil,否则返回其中一个玩家。你可以通过重写内部部分来使它更简洁,但可以说不太明确:

if p1c!=p2c then
  case p1c
    when "r" then p2c=="s"
    when "p" then p2c=="r"
    when "s" then p2c=="p"
  end ? player1 : player2
end