LoginSignup
17
16

More than 5 years have passed since last update.

ruby の 文字列の連接

Last updated at Posted at 2014-08-31

連接について

意外なことに、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

17
16
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16