Обратите внимание, что ваша функция и массив имеют одно и то же имя, vowels
.Это вызывает путаницу - вы можете подумать, что вы вызываете includes?
в глобальном массиве vowels
, но на самом деле ваш код пытается рекурсивно вызвать вашу функцию с идентичным именем без параметров, что приводит к ошибке.Так как Ruby разрешает вызовы функций без круглых скобок, Ruby обрабатывает эту строку:
vowels.include?(letter)
как
vowels().include?(letter) # <- wrong number of arguments!
Изменение имени вашей функции на что-то отличное от «гласных» вызывает эту ошибку, что делает болеесмысл:
undefined local variable or method `vowels' for main:Object
(repl):7:in `block in function_formerly_known_as_vowels'
(repl):6:in `each'
(repl):6:in `function_formerly_known_as_vowels'
(repl):12:in `<main>'
Это приводит к основной причине: нарушение инкапсуляции.Функция vowels
пытается получить доступ к состоянию в глобальной области.Это плохая практика (и она не будет работать в этом коде, поскольку массив vowels
на самом деле не является глобальным - ему понадобится префикс $
для имени переменной или другой способ сделать его видимым внутри области действия функции- см. этот ответ для деталей).Вместо этого передайте массив гласных в функцию в качестве параметра (и, возможно, обобщите функцию в процессе) или жестко закодируйте его внутри самой функции, поскольку можно предположить, что гласные не изменятся.
После разрешенияпроблема объема, следующая проблема заключается в том, что until
- это цикл.Как только letter
является согласной, она будет неоднократно помещаться в массив consonants
до тех пор, пока программе не хватит памяти.Вы, вероятно, имели в виду unless
.Даже здесь вам нужно будет break
или return
, чтобы выйти из цикла при нахождении гласного.
Наконец, пара семантических предложений: vowels
не очень точное имя функции.Он возвращает согласные до первого гласного, поэтому назовите его как таковой!Параметр "words" может вводить в заблуждение, поскольку он предлагает массив или серию слов, когда ваша функция работает с одним словом (или строкой, в общем случае).
Вот перезапись:
def front_consonants(word)
vowels = "aeiou"
consonants = []
word.each_char do |letter|
break if vowels.include? letter
consonants << letter
end
consonants.join
end
p front_consonants "stack" # => "st"