【问题标题】:Understanding impact of false in method了解方法中错误的影响
【发布时间】:2019-02-03 12:40:37
【问题描述】:

我的方法处理程序循环的真/假。代码接受一些整数,然后检查:

  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

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

【问题讨论】:

  • 方法内的任何return 语句都将结束任何后续评估。如果你想打破循环,你会使用break;如果你想进入循环的下一次迭代,你可以使用next

标签: ruby methods boolean boolean-operations


【解决方案1】:

我担心(并想确保)[它有效]。

它确实有效(几乎)。由于您写了&lt; 100 而不是&lt;= 100 的小错误。

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-30
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 2020-01-31
      • 1970-01-01
      • 2019-05-03
      • 2019-07-12
      相关资源
      最近更新 更多