Best ruby idiom for “nil or zero”

前端 未结 21 2056
日久生厌
日久生厌 2020-12-13 03:04

I am looking for a concise way to check a value to see if it is nil or zero. Currently I am doing something like:

if (!val || val == 0)
  # Is nil or zero
e         


        
相关标签:
21条回答
  • 2020-12-13 03:48

    I believe your code is incorrect; it will in fact test for three values: nil, false, and zero. This is because the !val expression is true for all values that are false, which in Ruby is nil and false.

    The best I can come up with right now is

    if val == nil || val == 0
      # do stuff
    end
    

    Which of course is not very clever, but (very) clear.

    0 讨论(0)
  • 2020-12-13 03:48

    Instead of monkey patching a class, you could use refinements starting in Ruby 2.1. Refinements are similar to monkey patching; in that, they allow you to modify the class, but the modification is limited to the scope you wish to use it in.

    This is overkill if you want to do this check once, but if you are repeating yourself it's a great alternative to monkey patching.

    module NilOrZero
      refine Object do
        def nil_or_zero?
          nil? or zero?
        end
      end
    end
    
    using NilOrZero
    class Car
      def initialize(speed: 100)
        puts speed.nil_or_zero?
      end
    end
    
    car = Car.new              # false
    car = Car.new(speed: nil)  # true
    car = Car.new(speed: 0)    # true
    

    Refinements were changed in the last minute to be scoped to the file. So earlier examples may have shown this, which will not work.

    class Car
      using NilOrZero
    end
    
    0 讨论(0)
  • 2020-12-13 03:50

    If you really like method names with question marks at the end:

    
    if val.nil? || val.zero?
      # do stuff
    end
    
    

    Your solution is fine, as are a few of the other solutions.

    Ruby can make you search for a pretty way to do everything, if you're not careful.

    0 讨论(0)
  • 2020-12-13 03:51

    You can use case if you like:

     case val with nil, 0
          # do stuff
     end
    

    Then you can use anything that works with ===, which is nice sometimes. Or do something like this:

    not_valid = nil, 0
    case val1 with *not_valid
          # do stuff
     end
     #do other stuff
     case val2 with *not_valid, false    #Test for values that is nil, 0 or false
          # do other other stuff
     end
    

    It's not exactly good OOP, but it's very flexible and it works. My ifs usually end up as cases anyway.

    Of course Enum.any?/Enum.include? kind of works too ... if you like to get really cryptic:

    if [0, nil].include? val
        #do stuff
    end
    

    The right thing to do is of course to define a method or function. Or, if you have to do the same thing with many values, use a combination of those nice iterators.

    0 讨论(0)
  • 2020-12-13 03:53

    Another solution:

    if val.to_i == 0
      # do stuff
    end
    
    0 讨论(0)
  • 2020-12-13 03:57

    This evaluates to true for nil and zero: nil.to_s.to_d == 0

    0 讨论(0)
提交回复
热议问题