かけ算の順序の昔話

算数教育について気楽に書いていきます。

Perl,Python,Rubyで「"3"かける5」

Perlでは,「3 x 5」は「"33333"」,「5 x 3」は「"555"」となります.

$ perl -v

This is perl 5, version 14, subversion 2 (v5.14.2) built for cygwin-thread-multi-64int
(以下略)

$ perl -de 1

Loading DB routines from perl5db.pl version 1.33
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1):   1
  DB<1> print 3 x 5
33333
  DB<2> print 5 x 3
555

というのも,この x は左オペランドを文字列,右オペランドを数値として,文字列の繰り返しを求める演算子だからです.乗算の演算子は,他の多くのプログラミング言語と同じ,* です.Perl演算子の一覧を知るには,ここがおすすめです.
オペランドが文字列になるか数値になるかは,演算子(というか評価)に応じて自在に変換されます.もう少し,評価させてみます.

  DB<3> print "3" x "5"
33333
  DB<4> print "5" x "3"
555
  DB<5> print "3" * 5
15
  DB<6> print 5 * "3"
15
  DB<5> print 3 * 5
15
  DB<6> print 5 * 3
15
  DB<7> print 3 . 3 . 3 . 3 . 3
33333
  DB<8> print 3 x 5 eq 3 . 3 . 3 . 3 . 3
1


Pythonでは,乗算も,文字列の繰り返しも,演算子は * です.どちらになるかは,オペランドで決まります.x は演算子ではありませんし,文字列どうしに * を適用するのも,エラーとなります.

$ python
Python 2.6.8 (unknown, Jun  9 2012, 11:30:32)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 3 * 5
15
>>> 5 * 3
15
>>> 3 x 5
  File "<stdin>", line 1
    3 x 5
      ^
SyntaxError: invalid syntax
>>> "3" * 5
'33333'
>>> "5" * 3
'555'
>>> 3 * "5"
'555'
>>> 5 * "3"
'33333'
>>> "5" * "3"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'


Rubyも,乗算,文字列の繰り返しともに,演算子は * です.
「"5" * 3」を評価すると,順当に「"555"」ですが,「3 * "5"」にはエラーが発生します.

$ ruby
ruby 1.9.3p327 (2012-11-10 revision 37606) [i386-cygwin]
$ irb
irb 0.9.6(09/06/30)
$ irb
irb(main):001:0> 3 * 5
=> 15
irb(main):002:0> 5 * 3
=> 15
irb(main):003:0> "3" * 5
=> "33333"
irb(main):004:0> 3 * "5"
TypeError: String can't be coerced into Fixnum
        from (irb):4:in `*'
        from (irb):4
        from /usr/bin/irb:12:in `<main>'

「整数 * 文字列」は「文字列 * 整数」を評価するよう,メソッドを再定義しましょう.

irb(main):005:0> class Fixnum; alias :star :*; def *(param); String === param ? param * self : star(param); end; end
=> nil

あとはご覧のとおり.

irb(main):006:0> 3 * "5"
=> "555"
irb(main):007:0> "3" * 5
=> "33333"
irb(main):008:0> 5 * "3"
=> "33333"
irb(main):009:0> "5" * 3
=> "555"
irb(main):010:0> 3 * "5" * 3
=> "555555555"

日本では,プログラミング言語においても,演算の意味を大事にしている…というのは言いすぎですかね.


関連: