我正在读this。使用此方法有什么好处:
user&.address&.state
过度
user.try(:address).try(:state)
我还是不明白。
最佳答案
(1)&.
通常比try(...)
短
根据情况,这可以使您的代码更具可读性。
(2)&.
是标准Ruby,而不是try
try
方法未在Ruby核心库中定义,而是在Rails库中定义。当您不是在开发RoR网络应用程序,而是在编写例如小 helper 脚本,这将很快变得相关。
(例如,与Bash相比,我更喜欢Ruby。)
(3)&.
使调试更容易
如果正在调用不存在的方法,则安全遍历运算符将引发错误。
>> "s"&.glubsch
NoMethodError: undefined method `glubsch' for "s":String
仅在
nil
上,它的行为会宽松:>> nil&.glubsch
=> nil
try
方法将始终返回nil
。>> "s".try(:glubsch)
=> nil
请注意,最新版本的Ruby和Rails就是这种情况。
现在,假设存在一种名为
glubsch
的方法。然后,您决定重命名该方法,但是忘记在一处重命名它。 (不幸的是,这可能是在ruby中发生的。。。)使用安全的遍历运算符,您几乎会立即注意到该错误(第一次执行该行代码时)。但是,try
方法将很乐意为您提供nil
,并且您会在程序执行的下游某处得到与nil
相关的错误。有时很难弄清楚这种nil
的来源。与
&.
盲目地返回nil
相比,try
的快速失败使调试变得更加容易。编辑:在这方面,还有与
try!
相同的变体&.
(带有爆炸声)。如果您不喜欢&.
,请使用它。(4)如果我不在乎某个方法是否实现,该怎么办?
那太奇怪了。由于这将是一种意外的编程方式,因此请使其明确。例如,通过使用
respond_to?
充实这两种情况(无论是否实现),然后分支出去。(5)
try
的块形式如何?除了方法名,还可以将一个块传递给
try
。该块将在接收者的上下文中执行;并且在该块内没有应用宽大处理。因此,只需一个方法调用,它的行为就与&.
相同。>> "s".try{ glubsch }
NameError: undefined local variable or method `glubsch' for "s":String
对于更复杂的计算,您可能更喜欢这种块形式而不是引入很多局部变量。例如。一连串的
foo.try{ glubsch.blam }.try{ bar }.to_s
将允许
foo
为nil
,但需要foo.glubsch
返回非nil
值。再一次,您可以以更简洁的方式使用安全遍历运算符执行相同的操作:foo&.glubsch.blam&.bar.to_s
但是,使用
try
的块形式进行复杂的计算恕我直言是一种代码味道,因为它妨碍了可读性。当您需要实现复杂的逻辑时,请使用描述性名称引入局部变量,并可能使用if
分支出nil
案例。您的代码将更具可维护性。HTH!