在Ruby中,有一个约定,方法名称以问号结尾,表示其返回值为boolean。为什么布尔值被认为如此特殊?如果你知道方法的返回值特别是布尔值,有什么方便吗?毕竟,在Ruby中,您可以将各种值返回(getter)方法插入到条件中,而无需关心它是否为布尔值。
我认为使用问号只是为了表示一个布尔值是一种浪费。应该有更多有用的用途。我有很多用例,我希望有一对getter和setter方法,其中setter方法应返回self
,以便我可以在方法链中使用它。将它们命名为get_foo
和set_foo
似乎很麻烦。我没有遵循惯例,而是想要命名一对像这样的getter和setter方法:
def foo?; @foo end
def foo v; @foo = v end
其中@foo
的值不是(必然)布尔值。 (除了可能批评违反惯例会使其他程序员感到困惑),这样做有什么问题吗?
答案 0 :(得分:4)
没有什么特别的,这只是一个惯例。一个问题可以用“是”或“否”来回答,但也可以用别人的名字来回答。
通过在带有问号的方法上返回布尔值,它表明它是一个显式行为。
如果您的回答是“是”或“否”,则代码的读者很容易识别您的方法的行为,甚至不用查看实现。另一方面,如果你让它返回任何其他类型,读者更难理解你的代码而不阅读你的类和方法定义。
使用布尔值只有两个可能的答案。如果返回值不是布尔值,那么它可以是任何东西,这根本没有帮助。您仍然需要查看方法实现。您应该总是进一步了解一些代码,但使用此约定会使其更简单。
答案 1 :(得分:4)
有一种惯例是在方法名称中使用问号来表示方法是谓词。 AFAIK,这个谓词不需要(通过惯例)返回一个布尔值,这要归功于truthy / falsey值的简单规则。
除了潜在的批评,打破会议会使其他程序员感到困惑,这样做有什么不对吗?
令人困惑和令人惊讶的同事程序员很糟糕。 Ruby不在乎。这只是一个惯例。惯例存在是有原因的。
答案 2 :(得分:3)
你可以在流控制结构中放置任何内容,但语义上的布尔值是合适的。 “如果”在真正的人类语言中通常采用布尔值,并且许多编程语言中的构造也是如此。 Ruby喜欢方便,并为语言中的所有内容赋予“真实性”值,这会影响它在布尔上下文中的行为。
换句话说,布尔值是唯一几乎专门用于流量控制的东西,因此惯例是使它们对于流量控制结构看起来“正确”。这是他们的原生环境。
(除了可能批评违反惯例会使其他程序员感到困惑),这样做有什么问题吗?
同样的意义上说,在20世纪20年代喜剧演员之后命名所有变量并没有错,不,这没有什么不妥。但是,与20世纪20年代喜剧演员之后命名所有变量的意义相同,这不是一个好主意。我所知道的任何语言 - 人类或计算机 - 都没有任何地方的问号意味着“得到”。因此,代码的语义与该约定不符。
答案 3 :(得分:2)
这个问题和答案归结为“POLS”AKA“Principle of Least Surprise”。
方法名称可以是由下划线分隔的字母和数字的随机选择,带有'!','?'如果我们选择这样做的话,'='就会洒在他们身上。它们可以在运行时由代码随机创建,并且,只要其余代码使用相同的字符排列,程序就会运行,Ruby会很高兴。
我们人类,程序员,确定所用方法的名称,表示某事物,特征或行动。尝试使用随机命名的方法会导致疯狂,或者至少是一个非常难以维护的程序。所以,相反,我们尝试使用合理的名称。有时它们是动词或形容词,有时它们更具描述性,因为该方法可以做几件事。
作为命名的一部分,有时我们希望提供有关方法行为的其他提示。按照Ruby的惯例,我们使用“!”警告编码人员该方法会改变某些东西或具有破坏性。 “=”表示该方法接受一个参数并将其分配给接收者/对象。它是一种setter方法,在许多其他语言中,使用“set_flag ...”或“set_value ...”作为名称是惯用的。这只是该语言的一种约定,并由该语言的开发人员遵循。
我们使用“?”在Ruby中询问有关对象的问题,无论是否对象都是如此。我们可以说“is_true?”还是“真的吗?”并表明我们正在测试某些事情是否属实。如果它是真的,或者是假的,那么它是一个布尔响应,所以我们返回一个真/假值。