【问题标题】:Is there a Ruby, or Ruby-ism for not_nil? opposite of nil? method?not_nil 是否有 Ruby 或 Ruby 主义?与零相反?方法?
【发布时间】:2023-03-04 21:03:01
【问题描述】:

我没有 Ruby 方面的经验,所以我的代码感觉“丑陋”且不习惯:

def logged_in?
  !user.nil?
end

我宁愿有类似的东西

def logged_in?
  user.not_nil?
end

但是找不到这样对立的方法nil?

【问题讨论】:

    标签: ruby-on-rails ruby null


    【解决方案1】:

    我可以根据nil? 方法的结果提供Ruby 风格的! 方法吗?

    def logged_in?
      user.nil?.!
    end
    

    如此深奥以至于 RubyMine IDE 会将其标记为错误。 ;-)

    【讨论】:

      【解决方案2】:

      我来到这个问题是为了寻找一个对象方法,这样我就可以使用Symbol#to_proc shorthand 而不是块;我发现arr.find(&:not_nil?)arr.find { |e| !e.nil? } 更具可读性。

      我找到的方法是Object#itself。在我的使用中,我想找到键 name 的哈希值,在某些情况下,该键被意外大写为 Name。单线如下:

      # Extract values for several possible keys 
      #   and find the first non-nil one
      ["Name", "name"].map { |k| my_hash[k] }.find(&:itself)
      

      other answers 中所述,在您测试布尔值的情况下,这将失败。

      【讨论】:

      • 这和my_hash.values_at("Name", "name").find有什么不同?
      • 完全一样。我在我的原始map 中还有一些其他逻辑,为了简单起见,我在本例中删除了这些逻辑,所以这里写的它可以与values_at 互换。重要的部分是传递给find
      【解决方案3】:

      请注意其他将present? 作为您问题的答案的答案。

      present? 与 rails 中的 blank? 相反。

      present? 检查是否有有意义的值。这些事情可能无法通过present? 检查:

      "".present? # false
      "    ".present? # false
      [].present? # false
      false.present? # false
      YourActiveRecordModel.where("false = true").present? # false
      

      !nil? 支票给出:

      !"".nil? # true
      !"    ".nil? # true
      ![].nil? # true
      !false.nil? # true
      !YourActiveRecordModel.where("false = true").nil? # true
      

      nil? 检查对象是否实际上是nil。其他:空字符串0false 等等,不是nil

      present? 非常有用,但绝对不是nil? 的反面。将两者混淆可能会导致意外错误。

      对于您的用例,present? 会起作用,但注意区别总是明智的。

      【讨论】:

      • 应该包含在接受的答案中。 false.blank?false.nil? 不同
      • present? 将查询您的数据库,nil? 不会,请注意
      【解决方案4】:

      当您使用 ActiveSupport 时,有 user.present? http://api.rubyonrails.org/classes/Object.html#method-i-present%3F,仅用于检查非零,为什么不使用

      def logged_in?
        user # or !!user if you really want boolean's
      end
      

      【讨论】:

      • 当心:present? 需要一个非空字符串。 ! "".nil? 返回 true,但 "".present? 返回 false。
      • 当心 2:我还要注意 !!user 不区分 user 为 nil 和 user 为 false ;双爆炸的用法将这两者混为一谈。因此,如果您真的想确定一个对象是否不是 nil(意思是:true、false、0、“”、nil 以外的任何值),您需要使用 berkes 不喜欢的 'ugly' 方法或@Tempus proposes below 的猴子补丁。当然,在这种情况下,not 不需要 nil(Rails 中的用户),the approach taken by Samo 是最不丑陋的,imo。
      • false.present? == false !false.nil? == true
      • 这个答案根本没有回答所提出的问题。这是对这个特定实现问题的答案。
      • 这个答案不正确。 false.nil?是假的,而假的。现在?也是假的!
      【解决方案5】:

      您似乎过于关心布尔值。

      def logged_in?
        user
      end
      

      如果用户为nil,那么logged_in?将返回一个“假”值。否则,它将返回一个对象。在 Ruby 中,我们不需要返回 true 或 false,因为我们在 JavaScript 中具有“truthy”和“falsey”值。

      更新

      如果您使用的是 Rails,则可以通过使用 present? 方法使这篇文章更好地阅读:

      def logged_in?
        user.present?
      end
      

      【讨论】:

      • 对以? 结尾的方法的期望是它返回一个布尔值。 !!value 是将任何内容转换为布尔值的经典方法。不完全一样,但在这种情况下,RoR 中的 Object#present? 也不错。
      • 这实际上在 Ruby 2.4 中使用 Path 中断了! [43] (pry) #<:assetsprecompile>: 0> assets_path.blank? true [44] (pry) #<:assetsprecompile>: 0> assets_path.to_s "/var/folders/rp/_k99k0pn0rsb4d3lm9l3dnjh0000gn/T/d20170603-96466-zk7di7" [45] (pry) #<:assetsprecompile>:0> assets_path.present? false [46] (pry) #<:assetsprecompile>: 0> assets_path.nil?假
      【解决方案6】:

      您可以使用以下内容:

      if object
        p "object exists"
      else
        p "object does not exist"
      end
      

      这不仅适用于 nil,也适用于 false 等,因此您应该测试它是否适用于您的用例。

      【讨论】:

        【解决方案7】:

        也许这可能是一种方法:

        class Object
          def not_nil?
            !nil?
          end
        end
        

        【讨论】:

        • 好主意。我由此得出没有not_nil?在红宝石。但这不应该是!self.nil? 而不是!nil?,还是selfimplicit?
        • 你不需要自我。它会被暗示。
        • 从实例方法(或访问器,实际上只是方法)读取时,会隐含 Self。设置值时,将在 Ruby 检查类实例中是否有同名的 setter 方法之前创建该方法的本地变量。一般规则:如果您有一个名为 xxx 的 attr_accessor,请使用“self.xxx = 3”(设置值)或“temp = xxx”(读取值)。使用“xxx = 3”不会更新访问器,只是在方法范围内新建一个变量。
        猜你喜欢
        • 2011-08-15
        • 2014-03-26
        • 1970-01-01
        • 2011-01-22
        • 2023-03-21
        • 2011-04-23
        • 1970-01-01
        • 2015-10-24
        • 1970-01-01
        相关资源
        最近更新 更多