Programing Language
プログラミング言語では様々な記号が演算子として定義されている。
RubyやHaskellやScalaでは演算子もメソッドとして作られている。
演算子には1項演算子、2項演算子、それに加えて(稀だが)3項演算子も プログラミング言語で使われる (原理的にはそれ以上のものも可能だが混乱するのでそれ以上のものは作られていないようだ)。
3項演算子としては、C言語とその流れを汲む言語で使われる、~ ? ~ : ~
の形のものが知られている(意味としては
if式による条件判定と同じ)。
よく見かける(この教程でもよく現れる)四則演算の演算子は、2項演算子に分類され、
演算の対象となる数値(など)がその両側に書かれ、左辺、右辺、あるいは 左オペランド、右オペランドと呼ばれる)。
(別資料の内容の要旨と補足)
+
*
はいずれも量指定子の意味を持つメタ文字。なので、
この文字そのものとして正規表現の中で使うには、
いずれかの方法でメタ文字としての意味を無効にさせて使う。
\
;
円記号として表示されることが多い)を直前に置いて「エスケープ」させる。[ ]
で囲んで単独の文字クラスにする([+]
[*]
のように)。 /
は(多くのプログラミング言語で)正規表現そのものを囲む記号として使われていて、正規表現の中で不用意に文字そのものとして使おうとするとエラーの原因になる(そこで正規表現が終わると解釈されるため)。対策としては2つある。
\
でエスケープ。/
以外の文字で正規表現を囲む。-
は、前述の+
*
とは逆に、正規表現の中の、文字クラスの中でのみ 特殊な意味を持ち、
-
を、文字そのものとして使いたいときは、
ブラケットのすぐ隣(文字クラスの左端または右端)に置くことで
上記の特殊な意味は解消される。(別ページ参照)
マッチした部分を取り出す方法を紹介しておく(キャプチャ)
"1+2+3" =~ /([-+*\/]|\d+)/ && $1
$
を使う。こうして取り出す操作を、マッチしなくなるまで繰り返せば scan代わりは実現できる。こんな形のコードになるだろう。
.*
で受け止めて ( )
で囲み(キャプチャ)、
後方参照で $2
として取り出して、
次のマッチに引き渡している。上記の6.5では、数値を表す文字列を整数に変換するために String#to_i
メソッドを使った。
このメソッドを使わないで変換するプログラムを考えてみよう。
考え方:
"531" ー> (((5)*10+3)*10+1)
その準備として:
"9".ord # ASCIIコードを数値で返す
"9".ord-"0".ord
# または
'0123456789'.index('7') # この方法でもいい
その大枠:
s="1234567"
s.split(//).reduce(0){|r,v| .... }
# s.each_char.reduce も使える
または:
r=0
a=s.split(//)
while c=a.shift do
# a.each または s.each_char.each も使える
...
end
r
今回示したプログラム(スキャナー部)が動作することを 各自で実行して確認しておいて下さい。 (作ったプログラム(またはその部分だけでも)をメールで提出のこと)
(関心のある人はぜひ) 文字列から整数への変換(.to_iを使わない)も自分で完成させてみて下さい。
上記の逆の変換(整数を文字列に):
(このコードは各自で意味の解読を試みて下さい)
def n2s(n)
n<=0? "" : n2s(n/10)+"0123456789"[n%10]
end
? :
を使った3項演算子(if式と意味は同じ)が関数の本体になっていて、n
が0(以下)ならば再帰呼出をせず空文字列を返す。+
は、文字列の連結を行う演算子 String#+
。+
の右辺は、n
の右端(1の位)の文字を(長さ1のStringとして)求める式。