【问题标题】:Ruby on Rails - unless multiple conditionsRuby on Rails - 除非有多个条件
【发布时间】:2024-04-27 09:15:02
【问题描述】:

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

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'

我希望替代字符串('eabc')返回('eabc'),因为我在除非块中声明了这一点,我传递了两个值。

我不明白为什么这不起作用,以及我可以做些什么来让 'eabc' 返回 'eabc'。

【问题讨论】:

    标签: ruby-on-rails ruby string methods gsub


    【解决方案1】:

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

    使用两个或:

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

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

    unless string =~ /(dabc|eabc)/

    既然你表明你正在使用 Rails,你也可以像这样使用in?

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

    【讨论】:

    • 请注意, ('dabc' || 'eabc') 的计算结果为 'dabc',这就是它适用于第二次测试的原因。
    • 我的错,这对我来说是一个可怕的错误。感谢您指出这一点。
    【解决方案2】:

    这是因为 (1) 'dabc' || 'eabc' 等价于 'dabc',而您的代码中没有任何地方 'eabc' 以有意义的方式出现,并且因为 (2) 它仅在满足条件时返回 nil根据你使用unless的方式。

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

    【讨论】:

      【解决方案3】:

      除了关于何时以及在什么情况下返回什么的晦涩技术细节的乐趣之外,我认为不更明确地返回没有什么好处。这个问题被提出并随后在 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
      

      【讨论】:

        【解决方案4】:

        'dabc' || 'eabc' 将始终等于 true,因为它仅表示 condition or condition 其中条件是一个字符串。由于字符串不是 nil 或 false,因此它的计算结果为 true。您可以检查字符串是否在数组值中:

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

        【讨论】:

        • 'dabc' || 'eabc' 的计算结果为 'eabc'(这又是真实的,因此总是满足条件),但它明显不同于 true