Я обеспокоен (и хочу убедиться), что [это работает].
Это работает (почти). С небольшой ошибкой, которую вы написали < 100
вместо <= 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)
), ...
Теперь, когда у нас есть несколько тестов, давайте попробуем немного переписать этот метод к чему-то более элегантному. Мы можем быть уверены, что это все еще работает, потому что тесты все еще должны пройти!
Вместо использования Array#each
с несколькими операторами return
мы можем вместо этого использовать Enumerable#all?
, чтобы сделать то же самое в гораздо меньшем количестве кода (если вы готовы отбросить 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