ruby:当总和为21时,添加数字并打印为true

ded*_*les 1 ruby sum splat

这是rubeque.com上给出的一个简单问题:编写一个接受任意数量整数的方法,如果总和为21,则将它们添加为true.否则返回False.它测试输入:

assert_equal twenty_one?(3, 4, 5, 6, 3), true
assert_equal twenty_one?(3, 11, 10), false
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所拥有的:

def twenty_one?(*nums)
  nums.inject(&:+)
end

if twenty_one? == 21 
  puts true
else 
  false
end    
Run Code Online (Sandbox Code Playgroud)

但我收到错误消息:

RuntimeError: The value '21' does not equal 'true'.
Run Code Online (Sandbox Code Playgroud)

我真的很困惑如何解决这个问题.是否可以将if/else语句放在方法中?如果这个问题非常基本,那就很抱歉.我是编程新手.

Aru*_*hit 5

你需要把你的方法写成

def twenty_one?(*nums)
  nums.inject(&:+) == 21
end
Run Code Online (Sandbox Code Playgroud)

这是一个小小的演示: -

require "minitest/autorun"

class Numerics
  def twenty_one?(*nums)
    nums.inject(&:+) == 21
  end
end

class TestNumerics < MiniTest::Test
  def setup
    @numeric = Numerics.new
  end

  def teardown
    @numeric = nil
  end

  def test_twenty_one?
    assert_equal @numeric.twenty_one?(3, 4, 5, 6, 3), true
    assert_equal @numeric.twenty_one?(3, 11, 10), false
  end
end
Run Code Online (Sandbox Code Playgroud)

让我们进行测试: -

[arup@Ruby]$ ruby test/test_numerics.rb
Run options: --seed 61602

# Running:

.

Finished in 0.001332s, 750.9402 runs/s, 1501.8804 assertions/s.

1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
[arup@Ruby]$
Run Code Online (Sandbox Code Playgroud)

在您的方法中,它返回了您尝试与之比较的Fixnum实例.这就是你得到错误的原因.如果你查看源代码,你会发现两个对象之间的比较是同一个类的实例,否则会抛出你得到的错误.21trueassert_equal

注意:你当然可以写这个nums.inject(&:+),nums.inject(:+)因为Ruby允许这种自由,#reduce/#inject特别是开箱即用的方法.

更新

Carles Jove Buxeda提出了一个很好的想法来设计这个问题.我的想法是将方法放在模块中,然后包含它来测试它的方法:

require "minitest/autorun"

module Numerics
  def twenty_one?(*nums)
    nums.inject(:+) == 21
  end
end

class TestNumerics < MiniTest::Test
  include Numerics

  def test_twenty_one?
    assert_equal twenty_one?(3, 4, 5, 6, 3), true
    assert_equal twenty_one?(3, 11, 10), false
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,如果我运行它:

arup_ruby$ ruby test/test_numerics.rb
Run options: --seed 1223

# Running:

.

Finished in 0.001067s, 937.2071 runs/s, 1874.4142 assertions/s.

1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
arup_ruby$
Run Code Online (Sandbox Code Playgroud)

很酷的主意!