。?红宝石中的(存在)算子?

时间:2012-03-11 23:52:46

标签: ruby null

Ruby中是否有.?运算符,在调用方法之前检查对象是否为nil

例如,如果我必须编码:

if person and person.neighbor and person.neighbor.house and person.neighbor.house.rooms
    person.neighbor.house.rooms.each do |room|
        blah
    end
end

有没有比检查所有内容更好的方法?

请不要说“代码以这些对象永远不能nil”的方式,我从API调用中获取这些内容并且无法控制它。

5 个答案:

答案 0 :(得分:5)

从Ruby 2.3.0开始,&."安全导航"运营商正是这样做的。而不是

person and person.neighbor and person.neighbor.house and person.neighbor.house.rooms

你现在可以做到

person&.neighbor&.house&.rooms

http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

答案 1 :(得分:3)

最简单的方法是使用andand gem,尽管还有其他一些非常简单的选项,例如thisthis等等。

答案 2 :(得分:1)

您要查找的方法是nil?

示例:

foo.nil?

有关针对nil值进行防御编程的更优雅方法,请参阅同一主题的question。例如,你可以写:

person.neighbor.house.rooms.each do |room|
    blah
end
rescue false

答案 3 :(得分:1)

对于第二种情况,检查对象是否有方法列表,您可以使用try方法

require "active_support/core_ext/object/try"
person.try(:neighbor).try(:house).try(:rooms).each do |room|
   blah
end

或我的try

版本
class Object
  def try(*args, &block)
    if args.empty? and block_given?
      begin
        instance_eval &block
      rescue NameError => e
        puts e.message + ' ' + e.backtrace.first
      end
    elsif respond_to?(args.first)
      send(*args, &block)
    end
  end
end

然后你可以做到这一点:

person.try{neighbor.house.rooms}.each do |room|
   blah
end

答案 4 :(得分:1)

为什么不

begin
    person.neighbor.house.rooms.each do |room|
        ...
    end
rescue NameError
    ...
end

异常处理程序是为了处理异常:)所以如果你依赖别人代码,你不应该阻止但是处理代码崩溃,而不是检查一切是否正常。