Notice your function and array have the same name, vowels
. That's causing confusion--you may think you're calling include?
on the global vowels
array, but actually, your code attempts to call your identically-named function recursively without parameters, hence the error. Since Ruby permits function calls without parentheses, Ruby treats this line:
vowels.include?(letter)
as
vowels().include?(letter) # <- wrong number of arguments!
Changing your function name to something other than "vowels" causes this error, which makes more sense:
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>'
This leads to the underlying cause: breaking encapsulation. The vowels
function attempts to access state in the global scope. This is poor practice (and won't work in this code since the vowels
array isn't actually global--it'd need a $
prefix on the variable name or another way of making it visible inside the function scope--see this answer for details). Instead, pass the array of vowels into the function as a parameter (and probably generalize the function in the process), or hardcode it inside the function itself since we can assume vowels won't change.
Having resolved the scope issue, the next problem is that until
is a loop. As soon as letter
is a consonant, it'll be pushed repeatedly onto the consonants
array until the program runs out of memory. You probably meant unless
. Even here, you'll need to break
or return
to exit the loop upon finding a vowel.
Lastly, a couple semantic suggestions: vowels
is not a very accurate function name. It returns consonants up to the first vowel, so title it as such! The parameter "words" is potentially misleading because it suggests an array or a series of words, when your function appears to operate on just one word (or string, generically).
Here's a re-write:
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"