わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

文字列の繰り返しに関する,スクリプト言語の違い

「次にRubyについて紹介していきます.Rubyそのものは,Webサービスの開発を意識して設計されたものではありませんが,本日の授業のはじめや,以前の回でもお知らせしてきたとおり,Ruby on Railsという,世界中で利用されているWebアプリケーションフレームワークは,Rubyなくして成立しないのです.
 (略)
 Rubyの特色として,すべてがオブジェクトである点を挙げることができます.他の代表的なスクリプト言語,『Perl』『Python』との間でですね,『文字列の繰り返し』の式の評価を見比べることで,その特徴を確認していきたいと思います.
 スライドに表示させている,表ですが…」

「『文字列の繰り返し』というのは,例えば"abc"という文字列を3回,繰り返して作られる文字列は,"abcabcabc"となる,ということです.
 この表では『5』という,長さ1の文字列を3回繰り返すための式を考えます.こういった繰り返しは,かけ算です."abc"や"5"なんかが,かけられる数---いや,数ではないですね,英語ではmultiplicandという単語で済むのですが,えっと,かけられる対象があって,3回なら『3』が,かける数,multiplierとなります.なお,かける数は正の整数に限定します.3.1回とか,マイナス1回とかは考えない,ということです.一応かける数が0というのも,考えることはできて,元の文字列が何であれ,0回の繰り返しなので,長さ0の文字列,空文字列になるべきなのですが,と,細かいところに入り込んでしまいました.話を戻しましょう.
 Perlで,"5" * 3という式を評価すると,15という整数になります.演算子の左右を交換して,3 * "5"という式についても,同じです.というのも,式としては文字列と整数のかけ算として,書いてあっても,これは文字列を数値に変換して,数値の乗算をすることになるからです.たし算も,同様です.
 なのですが,Perlで文字列の連結を行う演算子があります.『+』ではなく,『.』です.また文字列の繰り返しを求めるための演算子もありまして,『x』です.ということで,表の2行目は,"5" * 3ではなく,"5" x 3という式を評価すると,結果は"555"となることを示しています.
 3 x "5"はというと,"33333"です.結局のところ3 x "5"は"3" x 5と等価となります..x演算子においては,常にその左側を文字列,右側を数値とみなして,文字列の繰り返しを求めるわけです.
 2番目のスクリプト言語Pythonはというと,文字列と,繰り返し回数をきちんと認識してくれます.すなわち,"5" * 3の結果は"555"であり,3 * "5"の結果も"555"です.
 さてRubyですが…
 Rubyも"5" * 3については,期待される振る舞いと言っていいでしょう.結果は"555"です.
 しかし3 * "5"を評価させてみると,エラーが出ます.
 その理由ですが,表の備考欄に書いた通り,a * bという式は,a.*(b)と解釈されます.先ほど『すべてがオブジェクト』と言ったことと,関連するのですが,このa.*(b)というのは,aというオブジェクトに対して,*という名前のメソッドを呼び出します,そしてこのメソッドに与えるパラメータは,bですよ,というのを表します.
 "5" * 3を,"5".*(3)としたとき,文字列(Stringクラス)に対し,整数値(Integerクラス)のオブジェクト1つだけをとるメソッド*が,利用可能となっているので,そのメソッドを呼び出して『"5"の3つ分』*1を連結した文字列,"555"を得ます.
 次に,エラーになった式です.3 * "5"も,3.*("5")と表せます.この場合,Integerクラスに対して,Stringクラスのオブジェクト1つだけをとるメソッド*というのはおかしいよ*2,エラーだよ,というわけです.
 ここまで時間をとって解説しましたが,知っておいてほしいのは,Rubyの『すべてがオブジェクト』という特性を,『文字列の繰り返し』の式で確認できるということです.Webサービスの構築に寄与する話ではないので,試験には出さない予定です」

他のプログラミング言語は?

  • PHPPerlと同様に,「.」は文字列の連結を行う演算子となります.しかし「x」演算子はありません.
  • JavaScriptPerlと同様に,「*」はその左右が文字列であっても数値に変換して乗算を行います("5" * 3も3 * "5"も15).「+」は,その左右が文字列なら,他方も文字列にした上で連結します("5" + 3は"53",3 + "5"は"35",5 + 3も3 + 5も8).「.」は文字列の連結ではありませんし,「x」は演算子ではありません.

*1:関連:https://takexikom.hatenadiary.jp/entry/2024/11/04/055902

*2:「Integerクラスに対して,Stringクラスのオブジェクト1つだけをとるメソッド*は存在しない」というわけではありません.Integerクラスに対して,オブジェクト1つだけをパラメータにとるメソッド*を呼び出すことになり,その処理の中で,パラメータがStringオブジェクトなので,適切に計算できずエラーとなります.irbで3*"5"を実行すると,「'Integer#*': String can't be coerced into Integer (TypeError)」と表示されます.