Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么安全导航比使用try-in-Rails更好?_Ruby_Ruby On Rails 4 - Fatal编程技术网

Ruby 为什么安全导航比使用try-in-Rails更好?

Ruby 为什么安全导航比使用try-in-Rails更好?,ruby,ruby-on-rails-4,Ruby,Ruby On Rails 4,我在看书。使用此功能有什么好处: user&.address&.state 结束 我还是不明白。(1)&。通常比try(…)短。 根据场景的不同,这可以使代码更具可读性 (2) &.是标准的Ruby,而不是try 方法try不是在Ruby核心库中定义的,而是在Rails库中定义的。当您不是在开发RoR web应用程序,而是在编写小助手脚本时,这将很快变得相关。 (例如,我更喜欢Ruby而不是Bash。) (3) &.使调试更容易 如果调用不存在的方法,安全遍历操作符将抛出错误

我在看书。使用此功能有什么好处:

user&.address&.state
结束

我还是不明白。

(1)
&。
通常比
try(…)短。
根据场景的不同,这可以使代码更具可读性

(2)
&.
是标准的Ruby,而不是
try
方法
try
不是在Ruby核心库中定义的,而是在Rails库中定义的。当您不是在开发RoR web应用程序,而是在编写小助手脚本时,这将很快变得相关。 (例如,我更喜欢Ruby而不是Bash。)

(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
的来源可能很困难

使用
&.
快速而艰难地失败比使用
try
轻松地返回
nil
更容易调试

编辑:还有变体
try(砰的一声)在这方面的行为与
&.
相同。如果您不喜欢
&.
,请使用该选项

>> "s".try{ glubsch }
NameError: undefined local variable or method `glubsch' for "s":String
(4) 如果我不在乎方法是否实现了呢? 那会很奇怪。由于这是一种意想不到的编程方式,请明确说明。例如,使用
respond\u to?
充实这两个案例(实施与否),并将其分支

(5) 试试
的块格式怎么样?
块可以传递给
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
案例。您的代码将更易于维护

(6)速度 安全导航的速度几乎是使用try方法的4倍

输出

  1.310000   0.000000   1.310000 (  1.311835)
  0.360000   0.000000   0.360000 (  0.353127)

我不认为我们应该比较这两件事,因为他们做了其他的事情

给出这个例子
Person
class

班级人员
定义名称
“约翰”
结束
结束
尝试 如果不确定对象上是否存在给定方法,则应使用
try

person=person.new
person.name#=>“John”
person.email#=>命名错误:未定义的方法“email”#
person.try(:email)#=>nil
&. 如果不确定调用方法的对象是否为零,则应使用安全Nagiviation

person=nil
person.name#=>NoMethodError:nil:NilClass的未定义方法“name”
人名#=>零
它们不能互换使用 人们经常混淆这两种方法,因为您可以使用
try
而不是
&。

person=nil
person.name#=>NoMethodError:nil:NilClass的未定义方法“name”
人名#=>零
person.try(:name)#=>nil
但是您不能使用
&.
而不是
try

person=person.new
person.name#=>“John”
person.email#=>命名错误:未定义的方法“email”#
person.try(:email)#=>nil
人员和.email#命名错误:未定义的方法“email”#

下面是我今天的非建设性评论:感谢您没有使用
foo
作为默认变量
glubsch
更有趣。响应很老,但只是一个注释,在最后一点上,表示
try
版本和
&.
版本的行为不一样。例如,当foo为
nil
:try version将导致
nil.to_
,而
&。
version将尝试调用
blam
on
nil
并提出一个命名标准。事实上,具有完整ruby的真正相等的版本应该更像
foo&.yield\u self{|foo | foo.glubsch.blam}如果不考虑NIOFor的错误FO,就可以考虑ToSo< <代码>或更可读:<代码> Fo& & Fo.GubsCh。BLAM & Bar。toys这个例子确实是错误的。谢谢你指出这一点,@firetonton。我将把它放在这里提醒大家,复杂的方法调用链是维护的噩梦。在我的机器上,它似乎快了3倍,但当
foo
实际上不是零时,您忘记了测试用例。因此,我编写了以下基准测试:对于非nil对象,
&
似乎比
try
快8倍
  1.310000   0.000000   1.310000 (  1.311835)
  0.360000   0.000000   0.360000 (  0.353127)