为什么Ruby方法中使用感叹号?

Ruby中,一些方法有一个问号( ? ),问一个像include?这样的问题include? 询问是否包含有问题的对象,然后返回true / false。

但为什么有些方法会有感叹号( ! )而其他方法却没有?

这是什么意思?


#1楼

简单说明:

foo = "BEST DAY EVER" #assign a string to variable foo.

=> foo.downcase #call method downcase, this is without any exclamation.

"best day ever"  #returns the result in downcase, but no change in value of foo.

=> foo #call the variable foo now.

"BEST DAY EVER" #variable is unchanged.

=> foo.downcase! #call destructive version.

=> foo #call the variable foo now.

"best day ever" #variable has been mutated in place.

但是,如果你曾经称过一种方法downcase! 在上面的解释中, foo将永久改为downcase。 downcase! 不会返回一个新的字符串对象,而是替换该字符串,完全将foo更改为downcase。 我建议你不要使用downcase! 除非是完全必要的。


#2楼

最准确的说方法是用Bang! 是更危险或更令人惊讶的版本。 有许多方法可以在没有Bang的情况下进行变异,例如.destroy并且通常方法只有在核心库中存在更安全的替代方法的爆炸。

例如,在Array上我们有.compact.compact! ,两种方法都会改变数组,但是.compact! 如果数组中没有nil,则返回nil而不是self,这比返回self更令人惊讶。

我发现爆炸的唯一非变异方法是Kernel.exit! 这比.exit更令人惊讶,因为在进程关闭时你无法捕获SystemExit

Rails和ActiveRecord延续了这一趋势,因为它使用了更多“令人惊讶”的效果,例如.create! 这会在失败时引发错误。


#3楼

底线: ! 方法只是改变它们被调用的对象的值,而没有方法! 返回一个被操纵的值,而无需写入调用该方法的对象。

只用! 如果您不打算需要存储在您调用方法的变量上的原始值。

我喜欢做类似的事情:

foo = "word"
bar = foo.capitalize
puts bar

要么

foo = "word"
puts foo.capitalize

代替

foo = "word"
foo.capitalize!
puts foo

以防我想再次访问原始值。


#4楼

!

我认为这是一个爆炸性的变化,它会摧毁它之前的一切。 Bang或感叹号表示您在代码中进行了永久保存的更改。

如果你使用Ruby的方法进行全局替换gsub! 你做的替换是永久性的。

您可以想象的另一种方法是打开文本文件并进行查找和替换,然后保存。 ! 在你的代码中做同样的事情。

如果你来自bash世界,另一个有用的提示是sed -i具有类似的效果,可以永久保存更改。


#5楼

被称为“破坏性方法”他们倾向于更改您所指对象的原始副本。

numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers   # returns [nil,nil,nil,nil,nil]

#6楼

一般来说,方法结束! 表明该方法将修改它所调用的对象 。 Ruby将这些称为“ 危险方法 ”,因为它们改变了其他人可能引用的状态。 这是一个简单的字符串示例:

foo = "A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

这将输出:

a string

在标准库中,有很多地方你会看到一对类似命名的方法,一个用! 一个没有。 没有的那些被称为“安全方法”,并且它们返回原始的副本 ,其中应用于副本的更改,被调用者不变。 这是没有的相同例子!

foo = "A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

这输出:

A STRING
a string

请记住,这只是一个约定,但很多Ruby类都遵循它。 它还可以帮助您跟踪代码中修改的内容。


#7楼

! 通常意味着该方法作用于对象而不是返回结果。 从Ruby编程

“危险”或修改接收器的方法可能以尾随“!”命名。


#8楼

这个命名约定取自Scheme

1.3.5命名约定

按照惯例,总是返回布尔值的过程名称通常以“?”结尾。 这样的过程称为谓词。

按照惯例,将值存储到先前分配的位置(参见3.4节)的过程名称通常以“!”结尾。 这种程序称为变异程序。 按照惯例,突变过程返回的值未指定。


#9楼

感叹号意味着许多事情,除了“这是危险的,要小心”之外,有时你不能从中得到很多。

正如其他人所说,在标准方法中,它通常用于表示一种方法,该方法会导致对象自身变异,但并非总是如此。 请注意,许多标准方法更改其接收器并且没有感叹号( popshiftclear ),并且某些带感叹号的方法不会更改其接收器( exit! )。 例如,请参阅此文章

其他库可能使用不同的方式。 在Rails中,感叹号通常意味着该方法将在失败时抛出异常而不是静默失败。

这是一个命名惯例,但许多人以微妙的方式使用它。 在你自己的代码中,一个好的经验法则就是在方法执行“危险”操作时使用它,特别是当存在两个具有相同名称的方法时,其中一个方法比另一个方法更“危险”。 “危险”几乎可以表示任何意义。


#10楼

来自themomorohoax.com:

根据我的个人喜好,可以按照以下方式使用爆炸。

1)如果方法没有按照预期的方式执行,则活动记录方法会引发错误。

2)活动记录方法保存记录或方法保存对象(例如条带!)

3)一种方法可以做一些“额外”的事情,比如发布到某个地方,或做一些动作。

重点是:当你真正考虑是否有必要时,只使用一声巨响,以免其他开发人员烦恼,不得不检查你使用爆炸的原因。

爆炸为其他开发者提供了两个线索。

1)调用方法后没有必要保存对象。

2)当你调用方法时,db将被更改。

http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值