Ruby on Rails - 除非多个条件同时成立

5

我正在尝试替换一个表达式,除非该表达式是两个值之一。

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'

我期望substitute_string('eabc')返回('eabc'),因为我在unless块中声明了这个,我传了两个值。

我不明白为什么这样不起作用,我该怎么做才能让'eabc'返回'eabc'。

4个回答

2

('dabc' || 'eabc') 是一个布尔表达式,其计算结果为 true 并返回 'dabc'。

使用两个 or:

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

或使用 =~(正则表达式匹配):

unless string =~ /(dabc|eabc)/

由于您表示正在使用 Rails,您也可以像这样使用 in?

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


1
请注意,('dabc' || 'eabc') 的计算结果为 'dabc',这就是第二个测试成功的原因。 - Yanis Vieilly
我的错,那是我犯的一个可怕的错误。谢谢你指出来。 - Darkmouse

1
这是因为 (1) 'dabc' || 'eabc' 等同于 'dabc',且在代码中没有意义地出现 'eabc',以及 (2) 根据你使用的方式,只有当条件被满足时,unless 才会返回 nil
def substitute_string(string)
  case string
  when 'dabc', 'eabc' then string
  else string.gsub('abc', 'xyz')
  end
end

1
除了关于返回什么以及在什么情况下返回的晦涩技术细节带来的乐趣外,我认为不明确返回值没有太多优点。正是因为这个问题被提出并在 SO 上进行了辩论,才说明用这种晦涩的方式编写代码(确实是可行的代码)会导致开发人员对该代码的解释产生困惑,并导致软件出现错误。

我唯一看到的好处就是它只占据了一行。

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

我个人更喜欢以下方式,因为它清晰地表明了您的意图:
def substitute_string(string)
  return string if ['dabc', 'eabc'].include?(string)
  string.gsub('abc', 'xyz') 
end

0

'dabc' || 'eabc'始终等于true,因为它只是意味着条件或条件,其中条件是一个字符串。由于字符串不是nil或false,它被评估为true。您可以检查该字符串是否在数组值中:

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

2
'dabc' || 'eabc' 的计算结果为 'eabc'(因此始终满足条件,是真值),但它明确不同于 true - Holger Just

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接