Edited at

ruby の 文字列の連接

More than 3 years have passed since last update.


連接について

意外なことに、ruby には C言語と同じような文法の、文字列の連接がある。

p( "x" "Y" ) #=> "xY"

p( "x" 'Y' ) #=> "xY"
p( 'x' 'Y' ) #=> "xY"

String#+ はどうあがいてもメソッド呼び出しになる(と思う)ので、実行時の効率という点で、文字列の連接は意味がある。その辺りは Java や(たぶん)perl とは事情が違う。

で。

連接の結果がリテラルになるのであって連接自体が何かの操作というわけではないので、括弧は書けない。

p( ( "x" )"Y" ) #=> SyntaxError: unexpected ')', 以下略

この辺りも C/C++ と同様。

また、連接は演算ではないので、どんな演算子よりも優先順位が高い。

p( ! "x" "y" ) #=> false

p( "x" "y".size ) #=> 2
p( { "x" "y"=>"a" "b" } ) #=> {"xy"=>"ab"}

この点も C/C++ と同じ。


いろいろなリテラル

C/C++ と違って、ruby には色々な文字列がある。

p( ?x 'Y' ) #=> "xY"

p( 'x' ?Y ) #=> SyntaxError: unexpected ')', expecting ':'
p( %Q!x! "Y" ) #=> "xY"
p( 'x' %Q!Y! ) #=> SyntaxError: unexpected tFID,(以下略)

という感じで、順序に依存する。

文字列の後に ?% があると、演算子に見えてしまうんだとおもう。

ヒアドキュメントも同様

p( <<"HOGE" "Y" ) #=> "x\nY"

x
HOGE

p( <<HOGE "Y" ) #=> "x\nY"
x
HOGE

p( "x" <<"HOGE" ) #=> "xHOGE"
Y
HOGE
#=> Y と HOGE で、NameError: uninitialized constant

p( "x" <<HOGE ) #=> NameError: uninitialized constant HOGE
Y
HOGE
#=> Y と HOGE で、NameError: uninitialized constant


Groovy の場合

ちなみに。

groovy では文字列の連接のように見えることを書くとメソッド呼び出しになる。

"print" "x" // 「x」を出力


Python の場合

ciel さんのお陰で python も連接があるとわかったので調査。

#coding:utf-8

from pprint import pprint

# ダブルクオート・シングルクオート・三連引用符は区別せず連接する
pprint( "x" "Y" ) #=> 'xY'
pprint( "x" 'Y' ) #=> 'xY'
pprint( "x" """Y""" ) #=> 'xY'
pprint( """x""" 'Y' ) #=> 'xY'
pprint( '''x''' """Y""" ) #=> 'xY'

# prefix の u は、どれかひとつについていれば有効。
# 全部に必要な C/C++ とは異なる。
pprint( u'x' u'Y' ) #=>u'xY'
pprint( u'x' 'Y' ) #=>u'xY'
pprint( 'x' u'Y' ) #=>u'xY'
pprint( u'x' Ur'Y' ) #=>u'xY'
pprint( 'a' "b" '''c''' """d""" u'e' "f" '''g''' """i""" ) #=>u'abcdefgi'

# prefix の R は、ついているものだけについて有効。
# C++11 の R と同じ動作だと思う。
pprint( '\x78' '\x59' ) #=>'xY'
pprint( R'\x78' '\x59' ) #=>'\\x78Y'
pprint( '\x78' R'\x59' ) #=>'x\\x59'
pprint( uR'\x78' R'\x59' ) #=>u'\\x78\\x59'
pprint( r'\x78' u'\x59' ) #=>u'\\x78Y'

そもそも python に文字列の連接があるのが意外だったんだけど、

prefix の u がどれかひとつについていれば良いというのはさらに意外。


D言語の場合

D言語は C/C++ の強い影響下にあるのでどうせ連接もあるだろうと思って調べたら、やっぱりあった。

でも、どうせ C/C++ と同じルールだろうと思ったら、ちょっと違っていた。

詳しくは

http://www.kmonos.net/alang/d/lex.html

を参照のこと。

大事なところを引用しておくと:


演算子 ~ でつなげられているか、 あるいは単純に並べて書かれている文字列どうしは結合されます:


とのこと。

でも、~ でつなげるのと空白でつなげるのでは違いがあり、

  writeln("Hel" "lo W" "orld!".length); //=> 12

writeln("Hel"~"lo W"~"orld!".length); //=> エラー

となる。

緩募:文字列の連接のある言語( C/C++/ruby/python/D 以外で )


参考記事

tbpgr さんの

「Ruby | 文字列リテラル同士の標準的な結合方法と標準的ではない結合方法」

http://qiita.com/tbpgr/items/08014f867f7d8cc1200f