Best ruby idiom for “nil or zero”

前端 未结 21 2054
日久生厌
日久生厌 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:44

    My solution also use Refinements, minus the conditionals.

    module Nothingness
      refine Numeric do
        alias_method :nothing?, :zero?
      end
    
      refine NilClass do
        alias_method :nothing?, :nil?
      end
    end
    
    using Nothingness
    
    if val.nothing?
      # Do something
    end
    
    0 讨论(0)
  • 2020-12-13 03:45

    Rails does this via attribute query methods, where in addition to false and nil, 0 and "" also evaluate to false.

    if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
    

    However it has its share of detractors. http://www.joegrossberg.com/archives/002995.html

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

    I really like Rails blank? method for that kind of things, but it won't return true for 0. So you can add your method:

    def nil_zero? 
      if respond_to?(:zero?) 
        zero? 
      else 
        !self 
      end 
    end 
    

    And it will check if some value is nil or 0:

    nil.nil_zero?
    => true
    0.nil_zero?
    => true
    10.nil_zero?
    => false
    
    if val.nil_zero?
      #...
    end
    
    0 讨论(0)
  • 2020-12-13 03:46

    This is very concise:

    if (val || 0) == 0
      # Is nil, false, or zero.
    end
    

    It works as long as you don't mind treating false the same as nil. In the projects I've worked on, that distinction only matters once in a while. The rest of the time I personally prefer to skip .nil? and have slightly shorter code.

    [Update: I don't write this sort of thing any more. It works but is too cryptic. I have tried to set right my misdeeds by changing the few places where I did it.]

    By the way, I didn't use .zero? since this raises an exception if val is, say, a string. But .zero? would be fine if you know that's not the case.

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

    First off I think that's about the most concise way you can check for that particular condition.

    Second, to me this is a code smell that indicates a potential flaw in your design. Generally nil and zero shouldn't mean the same thing. If possible you should try to eliminate the possibility of val being nil before you hit this code, either by checking that at the beginning of the method or some other mechanism.

    You might have a perfectly legitimate reason to do this in which case I think your code is good, but I'd at least consider trying to get rid of the nil check if possible.

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

    nil.to_i returns zero, so I often do this:

    val.to_i.zero?
    

    However, you will get an exception if val is ever an object that does not respond_to #to_i.

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