情報科学概論
2000.5.16
Rubyの作者であるまつもとゆきひろ氏を本学に招いて下記のように講演会を行います。
日時:7月21日(金) 14:30-16:00
場所:3号館2階多目的ホール(予定)
この時間はエレクトロニクスセミナーAの時間ですが、情報科学概論の特別講義に充てます。また、前期期末試験の期間中ですが、出席とレポート提出をこの授業の単位取得のための必須要件とします。
数学において記号「=」は等号であるが一般的にプログラミングにおいては「=」記号は代入を意味する。
初めて見たときに驚くのは、
n = n + 1
という記述であるかもしれない。これは、変数nの値を1増やすという意味で繰り返し操作の時に、よく使われる。
テキストp.52に示されているインデックス式や属性に関しては、p.53のスクリプトで理解する。ここで、
#!/usr/bin/ruby
class Foo
def []=(x,y)
print "hello\n"
end
def attr=(x)
print "bye\n"
end
end
foo = Foo.new
foo[0] = 15
foo.attr = 20
のスクリプトにおいて、classとendで囲まれた領域はFooというクラスを定義している部分であり、その定義内容はまず初めのdef〜endでインデックス式[]=の内容を定義する。一見引数x,yを取っているように見えるが、その実体はhelloを出力するだけである。また、次のdef〜endは同様にattrを定義している。内容はbyeの出力である。
次に、
foo = Foo.new
があるが、これは少し説明が必要である。newというメソッドは教科書のp.191で出てくるが、あるクラスに属するオブジェクトを生成するメソッドである。上の一行は、Fooというクラスに属するfooというオブジェクトを生成する、ということを意味している。すなわち、上で定義した[]とattrを使ったオブジェクトの生成である。
その後で、
foo[0] = 15
foo.attr = 20
のような動作で一見代入を行っているように見えるが、教科書にあるようにこれは単に[]=やattr=というメソッドを起動しているだけなので、結局は上の定義通り、helloやbyeを出力する。わかりにくい動作であるが、実際にはこのようなスクリプトを書かないことが推奨されているので、必要に応じて別の形式で利用する。
多重代入
p.53-54に紹介されている多重代入は複数の変数に一度に代入したり、配列を扱うときに便利な機能である。スクリプトの例を挙げて説明する。
#!/usr/bin/ruby
ary=[1,2,3]
a, b = ary
c, = ary
print "a= ", a, ", b= ", b, "\n"
print "c= ", c, "\n"
上のスクリプトはまずaryという配列を定義し、その後で代入を行っている。aryは3つの要素を持つ配列であるが、
a, b = ary
では、二つの変数にだけ代入を行っているので、配列の先頭の二つの要素をa,bとして取り出せる。
c, = ary
の場合は要素を一つだけ取り出す。ここで注意するのは、cの後のカンマである。カンマがないとcに123すべての要素が入って配列になってしまう。自分で動作させてみて確認すること。
以下テキストにある例を順に挙げてスクリプトを書いておくので自分で動作させること。
例
#!/usr/bin/ruby
a, b, c = 1, 2
print "a= ", a, ", b= ", b, "\n"
print "c= ", c, "\n"
例
#!/usr/bin/ruby
a, (b, c), d = 1, [2, 3], 4
print "a= ", a, ", b= ", b, "\n"
print "c= ", c, ", d= ", d, "\n"
例
#!/usr/bin/ruby
a, *b = 0, 1, 2, 3
print "a= ", a, "\n"
i=0
print "b=["
while i < b.size - 1
print b[i], ", "
i = i + 1
end
j=0
if j = b.size - 1
print b[j]
end
print "]\n"
このスクリプトではaは通常の変数であるが、bは残りの要素がすべて入ってしまうので、配列となる。これを利用して下のような例を作ると、
例
#!/usr/bin/ruby
*a = 0, 1, 2, 3
i=0
print "a =["
while i < a.size - 1
print a[i], ", "
i = i + 1
end
j=0
if j = a.size - 1
print a[j]
end
print "]\n"
このように代入という作業だけで配列を作ることが可能となる。なお、上二つのスクリプトには配列らしく出力を表現するために2.12節で出てくる制御構造が用いられている。詳細はまた改めて紹介する。
例
#!/usr/bin/ruby
a, b, c = 1, *[2, 3]
print "a= ", a, ", b= ", b, ", c= ", c, "\n"
上の例は配列を展開して変数に代入するためのスクリプトの例である。
p.55の表2-3に種々の演算子が紹介されているが、今は眺めるだけでよい。実際に使用する際に個別に議論を行う予定である。ただし、p.56に書いてあるように、短絡演算子や範囲指定演算子の取り扱いは注意を要するので、使う際にはよく確認すること。
例
!=と!~の使い方
#!/usr/bin/ruby
a = 1
b = 2
print "a != b; ", a !=b, "\n"
print "!(a == b); ", !(a == b), "\n"
==は論理演算子であり、演算子の両側の物が等しいときに真となる。上の例では、a=1、b=2としたので、a==bは偽である。よって、その否定は真となるので実行結果はどちらの場合もtrueを返す。また
#!/usr/bin/ruby
a = "1"
b = "2"
print "a != b; ", a !=b, "\n"
print "!(a == b); ", !(a == b), "\n"
print "\n"
print "a !~ b; ", a != b, "\n"
print "!(a =~ b); ", !(a =~ b), "\n"
では=~演算子の動作の様子を確認している。=~はp.71ででてくる正規表現との一致を見る演算子である。数値の場合には二重引用符はなくても動作は可能であるが任意の文字列を比較するときには必要となる。自分で一致する文字列に変更してみて動作を確認すること。
自己代入演算子
代入の節の初めに説明したようにプログラミングにおいては
n = n + 1
というように自分自身に何かの演算を行って再び代入することがよく行われる。それを簡単に記述するために自己代入演算子が用意されている。自己代入演算子は元々の二項演算子に=を加えて表現されているので、その動作は二項演算子に従う。たとえば、上の例は
n +=1
と表現される。
if文とはもし〜ならば...を行う、というような動作を示す構文である。また、英語の意味上で反対になるunlessを用いた場合にはもし〜でなければ...を行う、というように変わる。頻繁に使用するのでよく理解しておく必要がある。また、Rubyにおける条件成立は教科書のp.58にあるように、「偽」で無いことであり、「真」であることとは異なっているので注意すること。
例
#!/usr/bin/ruby
def abs(n)
if n > 0
n
else
-n
end
end
for i in -2..2
print abs(i)
end
引数が-2から2までの整数の時、その絶対値を求めるスクリプトである。for文に対してはこの後で説明する。
条件演算子
教科書p.59にあるようにif文は条件演算子として使用できるが、無理して使う必要は無いので今は覚えなくても良い。ただし、教科書にある例文は説明が必要と思われるので以下に示しておく。
printf "I have %d kid%s.\n", n, if n == 1 then "" else "s" end
実際に実行してみるとわかるが、nの値が%dに入り、単数複数の別に従ってkidとkidsが使われる。ここで、printfはフォーマット付き出力を意味し、p.86で詳しく紹介される。簡単に言うと、出力する値を利用して文字列中にその数値を埋め込んだり、文字列を変更したりする機能を持つ出力文である。%dは対応する整数の値を出力し、%sは文字列を参照する。
結局、上の例ではnが1であれば、%d=1、%s=""(空の文字列)であり、それ以外では%dはn、%sは"s"になるので、上で示したような動作を行う。なお、nに整数ではない値を入れると、%dはnを越えない最大の整数になる。
一つの条件に対して真か偽かで場合分けする場合にはif文は有効であるが、複数の場合が存在するときには、if文でも可能であるがcase文を用いる方が便利である。教科書p.60の下の方にある例を試して見よ。