在Ruby中,有些方法带有问号(?),会问include?询问是否包含有问题的对象,然后返回true/false。

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

这是什么意思?


当前回答

这个命名约定来自Scheme。

1.3.5命名约定 按照惯例,程序的名称 总是返回一个布尔值 通常以“?”结尾。这样的程序 称为谓词。 按照惯例,程序的名称 存储值到先前 已分配的位置(见3.4节) 通常以“!”结尾。这样的程序 叫做变异程序。通过 方法返回的值 突变过程未指明。

其他回答

通常,以!结尾的方法指示该方法将修改调用它的对象。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类都遵循它。它还可以帮助您跟踪代码中修改的内容。

底线:!方法只改变被调用对象的值,而没有!返回一个被操纵的值,而不重写调用该方法的对象。

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

我喜欢这样做:

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

OR

foo = "word"
puts foo.capitalize

而不是

foo = "word"
foo.capitalize!
puts foo

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

简单的解释:

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。 我建议你不要用小写!除非完全有必要。

这个命名约定来自Scheme。

1.3.5命名约定 按照惯例,程序的名称 总是返回一个布尔值 通常以“?”结尾。这样的程序 称为谓词。 按照惯例,程序的名称 存储值到先前 已分配的位置(见3.4节) 通常以“!”结尾。这样的程序 叫做变异程序。通过 方法返回的值 突变过程未指明。

被称为“破坏性方法”,它们倾向于改变你所引用的对象的原始副本。

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]