简体   繁体   中英

Ruby on Rails - unless multiple conditions

I'm trying to substitute an expression unless the expression is one of two values.

def substitute_string (string)
  string.gsub('abc', 'xyz') unless string == ('dabc' || 'eabc')
end

substitute_string('jjjjjabc')
=> 'jjjjjxyz'

substitute_string('dabc')
=> 'dabc'

substitute_string('eabc')
=> 'exyz'

I expected substitute_string('eabc') to return ('eabc') since I stated that in the unless block, which I passed two values.

I don't understand why this doesn't work, and what I can do to make 'eabc' return 'eabc'.

('dabc' || 'eabc') is a boolean expression that evaluates to true and returns 'dabc'.

Use two or's:

unless string == 'dabc' || string == 'eabc'

Or use =~ (regex pattern match)

unless string =~ /(dabc|eabc)/

Since you indicated you're using Rails, you can also use in? like this:

unless string.in? ['dabc', 'eabc']

It is because (1) 'dabc' || 'eabc' 'dabc' || 'eabc' is equivalent to 'dabc' , and nowhere in your code does 'eabc' appear in a meaningful way, and because (2) it only returns nil when the condition is met according to the way you used unless .

def substitute_string(string)
  case string
  when 'dabc', 'eabc' then string
  else string.gsub('abc', 'xyz')
  end
end

Apart from the fun of obscure technicalities about what is returned when and in what situations, I don't see a lot of merit in not being more explicit with the return. The very fact that this issue was brought and subsequently debated on SO is exactly why writing code (working code to be sure) in this obscure fashion will lead to confusion for developers interpreting this code, and leads to buggy software.

The only benefit I see to this is that it's on one line.

def substitute_string(string)
  string.gsub('abc', 'xyz') unless ['dabc', 'eabc'].include?(string)
end

I personally would prefer the following as it makes it clear what your intentions are:

def substitute_string(string)
  return string if ['dabc', 'eabc'].include?(string)
  string.gsub('abc', 'xyz') 
end

'dabc' || 'eabc' 'dabc' || 'eabc' will always equal true since it just means condition or condition where condition is a string. Since a string is not nil or false it evaluates to true. You could check whether the string is in an array values instead:

def substitute_string(string)
  string.gsub('abc', 'xyz') unless ['dabc', 'eabc'].include?(string)
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM