首先,我想提供另一种答案。与其使用Ruby字符串连接
'v' + s.version.to_s
你也可以使用Ruby字符串插值,在这种情况下大多数人都会使用它。
"v
在Ruby中,
#{...}
类似于Shell脚本或Perl中的
${...}
。整个表达式都会被代码片段(
...
)的输出替代,该代码片段可以是变量、方法调用或任何其他代码片段。但这仅适用于双引号中(再一次地,就像在Shell脚本或Perl中一样)。
现在关于OP @DavidH对@RaffAl答案的评论:
我完全不了解Ruby。s.version是一个字符串,但我必须将其转换为字符串才能创建一个新字符串(明白为什么我头晕了吗!)。
Ruby是一种极其动态的语言,在其中一切都是对象,几乎所有的东西都是作为方法实现的,甚至大多数的运算符也是如此。例如:
a = b + c
实际上调用了
b
上的
+
方法(是的,在Ruby中这是一个有效的方法名),并传入参数
c
,所以它实际上与
a = b.+(c)
相同。
当你写:
s.version = '0.0.2'
看起来你只是给一个变量赋值,但实际上会调用setter方法,因为这段代码等同于:
s.version=('0.0.2')
是的,实际上该方法的名称为version=
(在Ruby中允许在方法名称中使用特定运算符)。在Java中,该方法很可能被命名为setVersion()
。只是因为您将字符串传递给setter并不意味着该字符串也会存储在任何地方。
当您调用时
x = s.version
事实上,您正在调用一个getter方法:
x = s.version()
在Java中,该方法的名称为
getVersion()
。而且这个getter方法不返回一个字符串,它返回一个
Version
对象。因此,你的初始代码应该是:
'v' + s.version
实际上是这样的:
'v'.+(s.version)
但问题在于,
String
类的
+
方法不知道如何附加
Version
类的对象,这就是它失败的原因。
所有Ruby类必须继承自另一个类,如果它们没有,则简单地继承自
Object
类,并且该类定义了一个
to_s()
方法,因此任何Ruby对象都知道
to_s
(在Ruby中,圆括号始终是可选的,
puts(“ Hello World”)
与
puts“ Hello World”
相同)。如果它们没有覆盖它,则打印类名和对象ID的编码,但许多类已经覆盖了此方法以返回更有意义的内容。
Version
类将版本作为字符串返回。
好的,那么为什么字符串插值还能工作呢?因为除非
#{...}
表达式的结果产生一个字符串,否则Ruby会调用该结果的
to_s
方法来获取一个字符串。