长零安全方法链

jdf*_*ino 5 ruby-on-rails activesupport

所以我知道一些我所知道的不同方法,并且我想探索各种方法的优缺点,这些方法有以下几种:

  • 可读性
  • 性能
  • 易于调试
  • OO原则(低耦合和高内聚)

从主动支持中明确使用try方法

person.try(:pet).try(:name).try(:upcase)
Run Code Online (Sandbox Code Playgroud)

使用救援无

person.pet.name.upcase rescue nil
Run Code Online (Sandbox Code Playgroud)

使用&&运算符链

person && person.pet && person.pet.name && person.pet.name.upcase
Run Code Online (Sandbox Code Playgroud)

猴子修补Object类,请参阅https://gist.github.com/thegrubbsian/3499234获取原始要点

 class Object

      def try_all(*methods)
        values = [self]
        methods.each do |method|
          value = values.last.try(method)
          return nil if value.nil?
          values << value
        end
        values.last
      end

  end

person.try_all(:pet, :name, :upcase)
Run Code Online (Sandbox Code Playgroud)

不要使用nil安全代码,而是在调用代码之前验证数据

#not a good implementation by any means    
def person_has_pet_with_name? person
  begin 
    return true if !person.pet.name.nil?
  rescue
    return false
  end
end

person.pet.name.upcase if person_has_pet_with_name?(person)
Run Code Online (Sandbox Code Playgroud)

Chr*_*lle 4

我个人对猴子补丁的看法是,除非没有其他办法,否则不要这样做(如果我真的想要猴子补丁,甚至比我三思而后行)。
除此之外,Rails 已经使对象变得臃肿了很多。所以我不会再建议自定义膨胀对象。
为什么不通过经典的委托人方法来避免违反德墨忒尔法则:

class Person
  attr_accessor :pet
  delegate :name_upcased, to: :pet, 
    prefix: true, allow_nil: true
end

class Pet
  attr_accessor :name
  def name_upcased
    @name.upcase if @name
  end
end

@person.try :pet_name_upcased
Run Code Online (Sandbox Code Playgroud)

您还可以阅读有关德墨忒尔定律的内容:不要违反德墨忒尔定律!Module#delegate
至少只要一个简单的条件就能解决它,我不会坚持使用Object#try ,因为查看“try”的来源,它比条件的成本更高。