第2回(10/9) オブジェクトの宣言 ・Class宣言、メソッド・変数、アクセサ ☆ 角度クラス、2次元座標クラス、行列クラス ※ 連絡事項:http://unicorn.ike.tottori-u.ac.jp/tokuhisa/himitsu/enshu4/index.html に授業資料があります。 ■ Ruby の変数 ・グローバル変数 $foo ・ローカル変数 foo ・インスタンス変数 @foo ・クラス変数 @@foo ⇒ list0201.rb ■ クラス と インスタンス ・クラス:オブジェクトの性質を定義するもの。 ・インスタンス:クラスを具体化したもの。 ● Class 宣言 class クラス名 メソッド1の定義 メソッド2の定義 メソッド3の定義 end ● 初期化のメソッド ・メソッド名が initialize ● メソッドの呼び出し ・「インスタンス.メソッド名」 ⇒ list0202.rb □□□ 演習1 □□□ 2次元座標クラス Point を次の通りに定義せよ。 - initialize メソッドは、x 座標と y 座標の2つの引数を持つ - インスタンス変数の変数名には、@x と @y を使う - 表示のための show メソッドは、例えば「(1,2)」と表示する メインルーチンの例: p1 = Point.new(1,2) p2 = Point.new(-5,3.3) p1.show p2.show 出力の例: (1,2) (-5,3.3) ⇒ prac0201.rb ■ 値を返す ・return ・実体が何であるかに注意! ⇒ list0203.rb ⇒ demo0203.txt □□□ 演習2 □□□ 2次元座標クラス Point に、原点からの距離を返すメソッドdistanceを作れ。 ちなみに、値 u の平方根は、Math::sqrt(u) で求まる。 メインルーチンの例: p1 = Point.new(3,4) puts p1.distance 出力の例 5.0 ⇒ prac0202.rb □□□ 演習3 □□□ 度およびラジアンを扱う角度クラス Angle を次の通りに定義せよ。 - initializeメソッドは、引数に、角度の「数値」、角度の単位「deg」または「rad」、を持つ - radメソッドは、ラジアンで角度を返し、degメソッドは度で角度を返す ちなみに、180(deg) = π(rad)、Math::PI は円周率の定数である。 メインルーチンの例: a1 = Angle.new(60,'deg') puts a1.rad puts a1.deg 出力の例 1.047197551 60 ⇒ prac0203.rb ■ アクセサ インスタンス変数を外部から読み書きするためのメソッド。 ・方法1:通常のメソッドを使う場合 ⇒ list0204.rb ・方法2:演算子を使う場合 ⇒ list0205.rb ・方法3:ruby の組込宣言を使う場合 ⇒ list0206.rb □□□ 演習4 □□□ 3x3の行列クラス Matrix を宣言し、行列同士の和、積を求めるメソッド add, mult を作れ。また、行列を表示するメソッド show を作れ。 ヒント: class Matrix def initialize(a = [[1,0,0],[0,1,0],[0,0,1]]) @m = a @size = 3 end def add(x) ans = Matrix.new for i を 0,1,2 とする for j を 0,1,2 とする ans.m[i][j] を @m[i][j] と x.m[i][j] の和とする end end return ans end - - - end ヒント: Ruby では、0..3 は 0,1,2,3、0...3 は 0,1,2 という意味のオブジェクト メインルーチンの例: x = Matrix.new([[1,2,3],[1,-1, 2],[-3,-4,1]]) y = Matrix.new([[-3,-2,-1],[2,-1,2],[3,4,4]]) x.mult(y).show ⇒ prac0204.rb ■ 宿題:(1)か(2)か選択して答えよ。もちろん両方正解でポイントアップ。 (1) 演習4に、逆行列を求めるメソッド invers を追加せよ。逆行列が求まらない時は nil を返せ(return nil)。 ⇒ work0201.rb (2) 演習4の初期化メソッド initialize には致命的なミスがある。 たとえば、 a = [[1,1,1],[2,2,2],[3,3,3]] x = Matrix.new(a) x.show a[1][1] = 0 x.show としてみよう。x の2回目の表示では、2行2列目の値が 0 になっている。a[1][1] への代入操作が x に影響している。これは行列クラスが直観的で使い易いかどうかという点で問題である。その対策として、initialize メソッドの1行目で、 @m = a を @m = a.dup と変更したが、効果が無かった。理由を説明し、改善を施した initialize メソッドを示せ。 ⇒ work0202.rb