我经常在Ruby中看到这种类型的代码,但我不明白。 我在谈论“?”和“!”字符。对于以下示例, 它们只是作为函数名称的一部分使用还是某种运算符?
unless n.is_a? Integer
prime_array = [] if prime_array.nil?
myarray.sort!
答案 0 :(得分:4)
Ruby的语法允许您将单个?
或!
后缀为您的方法名称(两者中的一个或多个都无效)。
这是为了支持一些根深蒂固的惯例:
method?
返回布尔值但不修改其接收者状态的方法应该使用?
。例如,如果要“询问”容器是否已排序,则可以使用my_obj.sorted?
。如果您想“询问”容器是否为空,则可以使用my_obj.empty?
。这些方法都不会修改其接收对象的状态。有关用于在不修改对象的情况下查询对象的?
方法的许多示例,请参阅String
,例如start_with?
和end_with?
。
method!
最后具有!
的方法破坏性地修改其对象状态。通过扩展,当一个方法可能破坏性地转换对象的状态时,通常会提供两个版本的方法,包括和不包含!
。对于数组,您可能有一对名为sort
和sort!
的方法。 sort
将按排序顺序返回数组的副本,而不修改原始副本。致电sort
后,您将拥有两份副本,包括原件的未修改版本。但是,sort!
将对数组进行原位排序,覆盖原始数组。
再次提到String
,我们有capitalize
等方法返回字符串的大写副本,capitalize!
方法将字符串大写:
x = "what"
y = x.capitalize
puts x # "what"; x is unchanged
puts y # "What"
x = "what"
y = x.capitalize!
puts x # "What"; x is changed in-place
puts y # "What"
值得注意的是,Rails对!
的语义有自己的约定。在Rails中,可能失败的方法(例如数据库写入)通常会返回true
或false
。 Rails使用!
来指示该方法应该失败并返回异常,而不是false
返回值。例如,my_record.save
将在失败时返回false
; my_record.save!
会引发异常。
答案 1 :(得分:2)
这些是方法名称的一部分。 Ruby约定是返回布尔值的方法最后用?
命名,而可能有害的方法用!
命名。