我的方法处理程序循环的true / false。该代码采用多个整数,然后检查:
代码是:
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
部分。我要确保关闭循环并返回到整个方法(而不是实际上只是报告false并停止该方法)的false值不会触发true值。
答案 0 :(得分:4)
我担心(并希望确保)[有效]。
它确实起作用(几乎)。稍有错误,您写了< 100
而不是<= 100
。
return
立即退出该方法。另一方面,关键字break
只会退出循环。
但不要只听我的话。 (并且在StackOverflow上询问某人您的代码是否有效不是测试它的有效方法!)让我们为您的代码编写一些 tests :
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)
)...... p
现在我们已经进行了一些测试,让我们尝试稍微重写一下该方法以使其更优雅。我们可以确信它仍然有效,因为测试仍然可以通过!
我们可以使用Enumerable#all?
来用更少的代码来完成同一件事,而不是将Array#each
与多个return
语句一起使用(如果您愿意放弃{{1 }}语句):
puts
然后,我们可以使用Comparable#between?
进一步简化此操作:
def number_validator(*numbers)
numbers.all? { |number| number.is_a?(Integer) && number > 0 && number <= 100 }
end
答案 1 :(得分:1)
Nadnerb,return
将结束代码的任何进一步延续,而break
将退出当前循环并继续执行下一组指令。