Это расширенный комментарий о коде OP в целом, так что, пожалуйста, не голосуйте против (голосование в порядке).
Вы начинаете с
new_vrms = Array.new[3] {"placeholder"}
@ Серхио определил вашу проблему здесь, но кроме этого нет необходимости инициализировать значение каждого элемента массива («заполнитель») или даже фиксировать размер массива. Действительно, вы, очевидно, хотите вернуть массив с how_many
элементами, а how_many
пока не известно. Поэтому вы должны просто создать пустой массив здесь:
new_vrms = Array.new(0)
, что совпадает с
new_vrms = Array.new
который чаще пишется
new_vrms = []
Далее вы спросите пользователя, сколько элементов должно быть в массиве:
how_many = gets.chomp!()
Если пользователь введет "3"
, gets
вернет "3\n"
и gets.chomp
вернет "3"
. Обратите внимание, что нет необходимости завершать метод (здесь chomp
) с ()
, когда у него нет аргументов. Кроме того, chomp!
не является неправильным, но обычно используется немутирующая версия chomp
. Вы хотите, чтобы how_many
было целым числом, но не строкой (gets
всегда возвращает строку). Поэтому вам необходимо преобразовать его в целое число:
how_many = gets.chomp.to_i
Если вы посмотрите на документ для String # to_i , вы увидите, что "123abc".to_i #=> 123
, то есть "123\n".to_i #=> 123
, что означает, что нам не нужно chomp
при преобразовании строки в целое число:
how_any = gets.to_i
Теперь мы знаем, сколько раз мы хотим повторить цикл (how_many
), поэтому вы захотите использовать итератор и блок вместо while
цикла:
how_many.times do |i|
...<your code to add elements to new_vrms>
end
new_vrms # return the computed value
См. Целое число # раз .
Вы повторяете код при расчете prefix
и suffix
, поэтому давайте сделаем это отдельным методом:
LETTERS = ('A'..'Z').to_a
#=> ["A", "B", "C",...,"X", "Y", "Z"]
def random_3_letters
LETTERS.sample(3).join
end
См. Array # sample , который обеспечивает более прямой способ вычисления случайных троек букв. (Кроме того, мы можем рисовать из массива заглавных букв, поэтому нам не нужно преобразовывать образцы в верхний регистр позже. 1 Я создал константу LETTERS
, чтобы нам не нужно было создавать массив каждый раз, когда вызывается метод. Теперь мы можем записать блок.
YEAR = "68"
how_many.times do |i|
prefix = random_3_letters
suffix = random_3_letters
aVRM = prefix + YEAR + SUFFIX
puts "#{aVRM} added to index #{i}")
new_vrms.push(aVRM)
end
new_vrms
На самом деле нет никаких оснований для определения переменных prefix
и suffix
, поскольку мы можем упростить это следующим образом.
YEAR = "68"
how_many.times do |i|
aVRM = random_3_letters + YEAR + random_3_letters
puts "#{aVRM} added to index #{i}")
new_vrms.push(aVRM)
end
new_vrms
Если вы хотите напечатать значение каждого элемента aVRM
, лучше всего делать это вне цикла - в более общем случае - вне метода, который вы оберните вокруг кода. Если оператор puts "#{aVRM} added to index #{i}")
извлечен из блока, переменная блока i
больше не используется, поэтому ее можно опустить:
YEAR = "68"
def doit
new_vrms = []
gets.to_i.times do
new_vrms << random_3_letters + YEAR + random_3_letters
end
new_vrms
end
Обратите внимание, что я изменил Array # push на более часто используемый Array # << и заменил переменные <code>how_many и aVRS
.
Опытный Rubyist может усилить это еще больше (хотя входные значения также будут проверены на достоверность в реальном коде):
LETTERS = ('A'..'Z').to_a
YEAR = "68"
def doit
gets.to_i.times.with_object([]) do |_,new_vrms|
new_vrms << (random_3_letters + YEAR + random_3_letters)
end
end
def random_3_letters
LETTERS.sample(3).join
end
doit # entering "4"
#=> ["ZPI68LWY", "PQV68HLD", "IZG68JCH", "EAC68WLY"]
Обратите внимание, что с помощью Enumerator # with_object мы удаляем оператор new_vrms = []
и new_vrms
в конце, последний, потому что with_object
заставляет блок возвращать «объект», значение new_vrms
.
1 Обратите внимание, что вы никогда не должны писать str = str.upcase!
, потому что str.upcase!
возвращает nil
, если str
уже обработан (и, следовательно, в str
не вносятся изменения). Смотрите Строка # upcase! . Многие методы «взрыва» ...!
возвращают nil
, когда в получателя не вносятся изменения.