为什么在Ruby中用空格隔开的两个字符串会连接起来?

46

为什么这在 Ruby 中可行:

"foo" "bar"
# => "foobar"

我不确定为什么字符串被连接在一起而没有出现语法错误。

我很好奇这是否是预期行为,以及解析器是否负责处理它(两个没有运算符的字符串被视为单个字符串),或者语言定义本身指定了这种行为(隐式连接)。


1
同样的事情在Python中发生。 - Alok
1
有趣。正如JKillian所说,它必须与两种语言共享的C背景有关。 - Lukas
2个回答

53
在C和C++中,字符串字面量相邻时会连接在一起。由于这些语言影响了Ruby,我猜它是从那里继承过来的。
现在在Ruby文档中有记录:请参见此答案Ruby仓库中的此页面,其中写道:

Adjacent string literals are automatically concatenated by the interpreter:

"con" "cat" "en" "at" "ion" #=> "concatenation"
"This string contains "\
"no newlines."              #=> "This string contains no newlines."

Any combination of adjacent single-quote, double-quote, percent strings will be concatenated as long as a percent-string is not last.

%q{a} 'b' "c" #=> "abc"
"a" 'b' %q{c} #=> NameError: uninitialized constant q

2
+1 参考文档,不过我认为重要信息可能应该添加到答案中。我无法找到“字符串字面值并置”的好术语进行搜索。谢谢。 - Lukas
2
这个特性存在于许多编程语言中(大概都是从C语言借鉴而来),在将长字符串分成多行时非常有用。它与简单地连接字符串(使用+、&或其他语言使用的符号)不同,因为它发生在“编译”时,因此仍然是一个字符串字面量,而不是在运行时评估的表达式。 - Tom
实际上,“只要百分字符串不是最后一个”并没有反映出真正的行为。从我尝试的情况来看,如果百分字符串不是第一个,但也不是最后一个,如 "a" %q{b} "c",链接会抛出 syntax error, unexpected tSTRING_BEG, expecting end-of-input 的语法错误。 - Glutexo

38

实现细节可以在Ruby源代码的parse.y文件中找到。具体而言,在这里

Ruby的string可以是tCHAR(例如?q),string1(例如"q"、'q'或%q{q})或string1string本身的递归定义的串联,这会导致像"foo" "bar"'foo' "bar"?f "oo" 'bar'这样的字符串表达式被串联起来。


1
对于这个发现表示赞赏。看起来是与解析器相关的“特性”。接受这个解释而不是一堆链接。 - Lukas
2
"a" 'b' %q{c} #=> NameError: 未初始化常量 q 为什么会导致错误? - Ingrid Morstrad
2
@IngridMorstrad 因为 % 被视为模数运算符,而不是字符串字面量的一部分。作为二元运算符,你提到的表达式被解析为 'ab' % (q{c}),其中块 {c} 传递给 q,但 q 并不存在(可能),因此出现了错误。 - Ahmad Sherif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接