0

在 Ruby 中,有一个约定,方法名称以问号结尾,表示它的返回值是布尔值。为什么布尔值被认为如此特别?如果您知道方法的返回值是特别布尔值,有什么方便的吗?毕竟,在 Ruby 中,您可以将各种返回值(getter)方法插入到条件中,而无需关心它是否为布尔值。

我认为仅使用问号来表示布尔值是一种浪费。应该有更多有用的用途。我有很多用例,我想要一对 getter 和 setter 方法,setter 方法应该返回self,以便我可以在方法链中使用它。get_foo并将它们命名为set_foo看起来很麻烦。我不想遵循约定,而是想像这样命名一对 getter 和 setter 方法:

def foo?; @foo end
def foo v; @foo = v end

其中的值@foo不是(必然)布尔值。(除了可能会批评打破惯例会混淆其他程序员),这样做有什么问题吗?

4

4 回答 4

4

在方法名称中使用问号表示方法是谓词是一种惯例。AFAIK,这个谓词不需要(按照惯例)返回一个布尔值,这要归功于真/假值的简单规则。

除了可能会批评打破惯例会混淆其他程序员之外,这样做有什么问题吗?

让程序员同胞感到困惑和惊讶是不好的。鲁比不在乎。这只是一个约定。约定的存在是有原因的。

于 2013-02-21T16:38:35.840 回答
4

没有什么特别的,这只是一个约定。一个问题可以用“是”或“否”来回答,也可以用其他东西来回答,比如某人的名字。

通过在带有问号的方法上返回布尔值,它表明它是一个显式行为。

如果您的答案是“是”或“否”,那么您的代码读者很容易识别您的方法的行为,甚至无需查看实现。另一方面,如果你让它返回任何其他类型,那么读者如果不阅读你的类和方法定义就更难理解你的代码。

布尔值只有两种可能的答案。如果返回值不是布尔值,它可以是任何东西,这根本没有帮助。您仍然需要查看方法实现。您应该始终进一步了解某些代码,但是使用此约定会使其更简单。

于 2013-02-21T16:37:36.100 回答
3

可以将任何内容放入流控制结构中,但语义布尔值是合适的。真实人类语言中的“如果”通常采用布尔值,许多编程语言中的构造也是如此。Ruby 喜欢使事情变得方便,并为语言中的所有内容分配一个“真实性”值,这会影响它在布尔上下文中的行为方式。

换句话说,布尔值是唯一几乎专门用于流控制的东西,所以约定是让它们看起来“正确”用于流控制结构。这是他们的原生环境。

(除了可能会批评打破惯例会混淆其他程序员),这样做有什么问题吗?

在同样的意义上,以 1920 年代喜剧演员的名字命名所有变量并没有错,不,这没有错。但是,就像以 1920 年代喜剧演员的名字命名所有变量一样,这不是一个好主意。在我所知道的任何语言——人类或计算机——中,问号都没有表示“获取”的意思。因此,您的代码语义不符合该约定。

于 2013-02-21T16:45:46.417 回答
2

这个问题和答案归结为“POLS”AKA“最小惊喜原则”。

方法名称可以是由下划线分隔的字母和数字的随机选择,用 '!'、'?' 如果我们选择这样做,'=' 会洒在它们身上。它们可以由代码在运行时随机创建,只要其余代码使用相同的字符排列,程序就会运行,Ruby 会很高兴。

我们人类,程序员,确定所用方法的名称,以表示某事、一个特征或一个动作。尝试使用随机命名的方法会导致疯狂,或者至少是一个非常难以维护的程序。因此,相反,我们尝试为事物使用合理的名称。有时它们是动词或形容词,有时它们更具描述性,因为该方法做了几件事。

作为该命名的一部分,有时我们希望提供有关方法行为的额外提示。按照 Ruby 的约定,我们使用“!” 警告编码人员该方法改变了某些东西或具有破坏​​性。“=”表示该方法接受一个参数并将其分配给接收者/对象。这是一个 setter 方法,在许多其他语言中,使用“set_flag...”或“set_value...”作为名称是惯用的。这只是该语言的约定,该语言的开发人员遵循。

我们用 ”?” 在 Ruby 中问一个关于对象的问题,关于该对象是否正确。我们可以说“is_true?” 还是“真的?” 并表明我们正在测试某件事是否属实。如果它是真或假,它是一个布尔响应,所以我们返回一个真/假值。

于 2013-02-21T18:12:04.220 回答