了解 false 对方法的影响

Understanding impact of false in method

我的方法处理 true/false 的程序循环。该代码采用多个整数,然后检查:

  1. 如果提交的值为数字
  2. 如果数字在 1 到 100 之间

密码是:

def self.number_validator(*numbers)
    numbers.each do |number|
        unless number.is_a?(Integer)
            puts "#{number} is not an integer" 
            return false
        end
        unless number > 0 && number < 100
            puts "#{number} is out of range"
            return false
        end
    end
    return true
end

我的理解是 returning false 将退出整个方法。我很担心并希望确保它不会只破坏循环和 return 到 return true 部分。我想确保 true 值不会被 false 值触发,关闭循环并返回到整个方法(而不是实际上只是报告 false 并停止该方法)。

I'm concerned (and want to make sure) that [it works].

它确实有效(几乎)。由于您写的 < 100 而不是 <= 100.

的小错误

return 立即退出该方法。另一方面,关键字 break 只会退出循环。

但不要只相信我的话。 (并且在 Whosebug 上询问某人您的代码是否有效并不是测试它的有效方法!)让我们为您的代码写一些 测试

require 'rspec'

RSpec.describe 'number_validator' do
  subject { number_validator(*input) }

  context 'integers only (valid input)' do
    let(:input) { [1, 5, 80, 100] }
    it { is_expected.to eq true }
  end

  context 'non positive integer' do
    let(:input) { [1, 5, 0] }
    it { is_expected.to eq false }
  end

  context 'integer greater than 100' do
    let(:input) { [1, 5, 101] }
    it { is_expected.to eq false }
  end

  context 'non integer' do
    let(:input) { [1, 5, 'BAD'] }
    it { is_expected.to eq false }
  end
end

如果你愿意,你也可以写更多的边缘案例,例如如果没有给定输入 (number_validator()),或负数 (number_validator(-1)),或非整数 (number_validator(3.5)),...

怎么办

现在我们已经进行了一些测试,让我们尝试稍微重写该方法以使其更优雅。我们可以确信它仍然有效,因为测试应该仍然通过!

我们可以使用 Enumerable#all? 用更少的代码完成同样的事情,而不是使用 Array#each 和多个 return 语句(如果你愿意放弃 puts 语句):

def number_validator(*numbers)
  numbers.all? { |number| number.is_a?(Integer) && number > 0 && number <= 100 }
end

然后我们可以进一步简化这个,使用 Comparable#between?:

def number_validator(*numbers)
  numbers.all? { |number| number.is_a?(Integer) && number.between?(1, 100) }
end

Nadnerbreturn 将结束代码的任何进一步延续,而 break 将退出当前循环并继续执行下一组指令。