关闭。这个问题是opinion-based .它目前不接受答案。
想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.
7年前关闭。
Improve this question
所以我知道我知道的一些不同的方法,我想探索各种标准的各种方法的优缺点,这些标准是:
显式使用主动支持的 try 方法
person.try(:pet).try(:name).try(:upcase)
使用救援零
person.pet.name.upcase rescue nil
使用 && 运算符链
person && person.pet && person.pet.name && person.pet.name.upcase
Monkey 修补 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)
没有零安全代码,而是在调用代码之前验证数据
#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 已经使对象膨胀了很多。所以我不建议更多的自定义腹胀对象。
为什么不通过经典的委托(delegate)方法避免违反得墨忒耳法则:
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
您也可以在 Do not break the law of Demeter! 上阅读得墨忒耳定律。和 Module#delegate .至少我不会坚持Object#try只要一个简单的条件解决它,因为查看“尝试”的来源它比条件更昂贵。
关于ruby-on-rails - 长零安全方法链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25758830/