2
vowels = "aeiou"
"hello".include?(vowels) # ==> false

but if I add ! to the statement it works fine:

!("hello".include?(vowels) # ==> true
4
  • 1
    Welcome to SO! Please read "How to Ask" and its linked pages. Commented May 5, 2020 at 4:02
  • Welcome James. My big tip for using stackoverflow, is if I get stuck, I often add a question here with the plan to leave it overnight and see what answers I get. I also find it useful to gather my thoughts. Keep asking on here and it'll definitley help you grow as a developer. Commented May 5, 2020 at 4:38
  • Hey @JamesTheGuy if you're happy with one of the answers please make sure you accept an answer. It makes it worth if for those that offer assistance. If it's not answered yet, comment here and we'll help you further. Commented May 14, 2020 at 5:58
  • @JamesTheGuy Poke. Pls review and accept an answer. Commented Aug 27, 2021 at 1:58

4 Answers 4

3

.include? assesses the provided string as a whole word, so what your method says is, 'does "hello" include the whole sub-word "aieou" as part of it.' This is why it's false in the first instance, as your string "hello" does not include the word "aeiou".

Try this and you'll get true:

vowels = "llo"
"hello".include?(vowels) # ==> true

Secondly, you're misreading what the bang ("!") is doing. It's not making your method work, all it does is reverse the result, so when a bang is added, any true statement becomes false and any false statement when a bang is added becomes true.

Try these:

> true
> !true
> false
> !false

You can prove it to yourself with this code:

vowels = "llo"
!"hello".include?(vowels) # ==> false

One good place to play with small Ruby logic questions is with IRB or in Rails projects with rails console, which extends IRB. Open the terminal/commmand prompt on your computer and type irb to bring up a Ruby prompt (you likley knew this, I'm just sharing it in case it helps).

You want to cycle through each of your vowels and check each individually to see if it's included, and if it is, update the result to true.

The takeaway is that when there is a collection of things to go through, you'll usually want to cycle through them using each, assessing one at a time.

vowels = "aeiou"
result = false
vowels.each_char do |char| 
  result = true if "hello".include?(char) 
end
puts result

There are shorter ways to do this, but this is clean, simple and easy to understand, which happens to be a good measure of good code also.

Sign up to request clarification or add additional context in comments.

2 Comments

Elegant code is not necessarily the shortest or most cryptic. In the old days, when writing assembler and C we'd count clock cycles and instructions emitted. Now, given the state of compilers and interpreters, it doesn't pay off as the tools are often smarter than we are and optimize the code for us. We can actually make the code run more slowly if we get too fancy with our assumed improvements. That's why premature optimizing is a bad thing - if we don't know exactly what's wrong we can make it worse.
vowels.each_char.any? {|char| "hello".include?(char) }.
1

Evolve already explained in his answer why your version with include? doesn't work.

A method to check if a string contains at least one vocal might look like this in Ruby:

"hello".match?(/[aeiou]/i)
#=> true
"hxllx".match?(/[aeiou]/i)
#=> false

match? takes a regexp and returns true when the string matches the pattern. /[aeiou]/i is a regular expression that matches when any of ([...]) the chars in the list aeiou are found in the string at least once. The i at the end makes the whole expresion as case-insensitive.

Comments

0

I use this to explain how ! (not) works:

true    # => true
false   # => false

!true   # => false
!false  # => true

!!true  # => true
!!false # => false

Remember that in Ruby, nil and false are false, everything else is true. Other languages might treat 0 as false also, and that can trip up people just learning Ruby:

foo = nil   # => nil
bar = 0     # => 0
baz = 1     # => 1

!foo = nil  # => true
!bar = 0    # => false
!baz = 1    # => false

!!foo = nil # => false
!!bar = 0   # => true
!!baz = 1   # => true

And not is the long form of !:

!true     # => false
not true  # => false
!false    # => true
not false # => true

You'll often see !! used to convert a value to its true/false equivalent.

Comments

0

As @Evolve already said, x.include?(y) tests whether y is a substring of x. You want to know, whether x ('hello') includes at least one character from y ('vowels'). This can be done by x.split(//).any? {|c| y.include?(c)}. The split(//) turns the string into an array of characters, and the any? tests whether at least one array element fulfills the property specified in the code block.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.