1

I have this line of code:

if self.include?("van " || "de " || "von ")

why doesn't the block included after this line execute when the third alternative of the or-operator is true?

When my string is "von wartburg" the block doesn't execute, but when my string contains "van" or "de" then it does.

Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
thiebo
  • 1,339
  • 1
  • 17
  • 37

4 Answers4

3
self.include?("van " || "de " || "von ")

Will ALWAYS evaluate to

self.include?("van ")

Why? Because of how || works.

"van " || "de " || "von "
# ↑↑↑↑↑↑ evaluates to "van " and does not give a slightest shoe about the rest

See String#include - it accepts a substring and offset as arguments.

What you need is the following:

["van ", "de ", "von "].any? { |substring| self.include?(substring) }
Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
1

The 'or' will always evaluate "van " because of how || works.

Try using a regular expression like:

self =~ /^(van\ |de\ |von\ )/
Community
  • 1
  • 1
Navarro
  • 1,284
  • 2
  • 17
  • 40
0

I think what you want is

if self.include?("van ") || self.include?("de ") || self.include?("von ")

Having the || inside the call to include? makes it only evaluate the first string. You want to test include? for each case.

River
  • 8,585
  • 14
  • 54
  • 67
0

Well it doesn't work for "de " either

2.3.0 :004 > "van test".include?("van " || "de " || "von ")
 => true
2.3.0 :005 > "de test".include?("van " || "de " || "von ")
 => false
2.3.0 :006 > "von test".include?("van " || "de " || "von ")
 => false

When you run String#include?("van " || "de " || "von ") you pass only one argument to the function: "van " || "de " || "von ".

Boolean OR (||) will return the first element of the list that evaluates to true. So this is strictly identical to String#include?("van ").

I know only two ways to do what you were trying to do in just one line :

  • You can make a table of substrings to test and use any? over it

    ["van ", "de ", "von "].any? { |s| string.include?(s) }

  • Or you can use a regex (in which the or operator (|) does exactly what you want)

    /van |de |von / =~ string

asymmetric
  • 3,800
  • 3
  • 34
  • 52