.?(существование) оператор в рубине? - PullRequest
2 голосов
/ 12 марта 2012

Есть ли в 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 ]

5 голосов
/ 13 января 2016

Начиная с 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/

3 голосов
/ 12 марта 2012

Проще всего использовать гем и , хотя есть и другие, довольно тривиально реализованные опции, такие как this или this , илии т.д.

1 голос
/ 12 марта 2012

почему бы и нет

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

Обработчики исключений созданы для обработки исключений :) Поэтому, если вы зависите от чужого кода, вам не следует предотвращать, а обрабатывать код для сбоя, а не проверять, все ли в порядке.

1 голос
/ 12 марта 2012

Во втором случае, проверяя, есть ли у объекта список методов или нет, вы можете использовать try method

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
1 голос
/ 12 марта 2012

Метод, который вы ищете: nil?

Пример:

foo.nil?

Более элегантные подходы к программированию защиты от значений nil см. В моем вопросе. на ту же тему.Например, вы можете написать:

person.neighbor.house.rooms.each do |room|
    blah
end
rescue false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...