长的 nil 安全方法链 [英] Long nil safe method chains

查看:45
本文介绍了长的 nil 安全方法链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我知道一些我知道的不同方法,我想探索各种方法的优缺点,这些方法是:

So I know of a few different approaches that I am aware of and I want explore the advantages and disadvantages of the various ways for various criteria which are:

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

明确使用来自 active support 的 try 方法

Explicitly using the try method from active support

person.try(:pet).try(:name).try(:upcase)

使用救援 nil

person.pet.name.upcase rescue nil

使用 &&运营商链

Using an && operator chain

person && person.pet && person.pet.name && person.pet.name.upcase

猴子修补 Object 类,参见 https://gist.github.com/thegrubbsian/3499234 为原始要点

Monkey patching the Object class, see https://gist.github.com/thegrubbsian/3499234 for the original gist

 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)

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

Don't have nil safe code, instead validate the data before you call the code

#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)

推荐答案

我个人对猴子补丁的一般看法是,除非没有其他方法,否则不要这样做(如果我真的想要猴子补丁,我会三思而后行)).
除了 Rails 已经膨胀了很多对象.所以我更不建议自定义膨胀对象.
为什么不通过经典的委托方法避免违反德米特法则:

My personal opinion about monkey patching in general is do NOT do it unless there is no other way (and even than I think twice if I really want to monkey patch).
Besides Rails already bloated objects a lot. So I'd not suggest custom bloating objects even more.
Why not avoiding to break the law of Demeter by the classic delegator approach:

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

您还可以在 不要违反德米特法则!Module#delegate.
至少我不会坚持 Object#try 只要一个简单的条件解决它,因为查看'try'的来源比条件成本更高.

You can also read about the law of Demeter at Do not break the law of Demeter! and Module#delegate.
At least I would not stick to Object#try as long as a simple condition solves it, because looking at the source of 'try' it is more costly than the condition.

这篇关于长的 nil 安全方法链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆