【发布时间】:2009-11-11 21:02:20
【问题描述】:
I have a class 公开了一个字符串值和一个 int 值(分别是命令输出和退出代码)。除了通过to_s 和to_i 暴露它们之外,我还使用to_str 和to_int,像这样:
class Status
def to_s
@output
end
alias :to_str :to_s
def to_i
@status.exitstatus
end
alias :to_int :to_i
end
我的想法是能够在尽可能多的情况下使用这个对象。将其强制转换为字符串或 int 会增加可用性。例如,我可以将对象与字符串连接起来:
a_string = "Output was: " + results
(我想以此作为 int 强制的示例,但 Fixnum.+ 不喜欢它,因此它实际上不起作用:)
an_int = 1 + results
到目前为止,我所读到的所有内容都表明这可能是一件“坏”的事情。常见的主题是这样的:“当您的对象可以表示为字符串/int 时使用to_s/to_i,但只有当您的对象从根本上字符串/整数”。
毫无疑问,我的课程“根本上”不是字符串或 int。然而 我对这条规则有一些问题:
- 它使我的课程不太灵活/不可用。例如:如果我没有 Status.to_str,我无法使用 String.+ 将 Status 输出与另一个字符串连接起来。
- 这似乎违反了鸭式打字的精神。对象的用户(即:获取它作为参数的方法)不应该关心这个对象是什么,它应该只关心它可以做什么。 (在这种情况下,“do”表示“可以表示为字符串/int”。)
- “基本上是一个字符串/整数”的论点对我来说非常模糊。例如,您会看到
Float.to_int被多次提及。故事是这样的,因为浮点数总是有一个整数部分,to_int是一个有效的方法。但是,我认为这是虚假的:浮点数 not 是一个整数(因为它有一个非整数分量),因此试图将它们的“类型”等同起来没有多大意义。您可以合法地将浮点数转换为整数(通过截断),但我可以说我也可以将我的状态转换为整数(通过“截断”所有的非退出代码信息)。
所以,我的问题是:在实施to_str 和to_int 时有什么真正的(即:实际的)危害?
更新:Jörg W Mittag 举了一个让我想到一些事情的例子。换个说法:当您已经拥有to_s/to_i 时,是否真的需要拥有to_str/to_int? (除了特定方法已经期待 to_str 而不是 to_s)
例如,在 Jörg 的 Array.join 示例中,数组成员通过 to_s 转换,而分隔符通过 to_str 转换。但这真的有必要吗?如果 Array.join 改为调用 separator.to_s,那么您可以成功地将更多对象传递给它(例如:整数、符号等)并获得更大的灵活性。 Ruby 是否会从这种分离中受益?
【问题讨论】:
标签: ruby duck-typing