解説 10月(4)

今回の学習項目です。


クラスを使った部品化

課題1

クラスを使ったプログラムの部品化(コンポーネント化)

今日の課題は9月に作ったアドレス帳プログラムをクラスを使ったプログラムに作り変えることです。
クラスを使ったプログラミングをすることで、プログラムを部品化(コンポーネント化)することができます。 そうすることで、プログラムの開発をずっとやりやすくすることができます。
「名簿を操作する」という機能(働き)を一つの部品にしてまとめておくと、開発に都合がよいことがたくさんあります。 一つの機能を持つプログラムとして独立させることで、その部分の改善を容易に行うことができるようになります。 例えば、今出来ているプログラムを使って、実際に名簿の検索のCGIのプログラムを実現して実際に使ってもらっていても、この部分の改善を安心して行うことができます。 うまくいかなければ現在働いているのを使い続ければよいだけですから。 万一新しいプログラムにバグがあってもこの部分だけを元に戻せば元通り働くでしょうから安心です。

関数を使うことも部品化の一つの方法ですが、クラスを使うことで、もっと安定した部品化を達成できます。

課題1-1

次のプログラムは、アドレス帳ファイル(address_list.txt)を読み込んで、ハッシュ表として記録するプログラムをクラスを用いて実現したものです。
これを実行したとき、obj(AddressFileのインスタンス)のインスタンス変数meiboの中身にアクセスする(中身を表示したり書き換えたりする)には、どのような方法でできるか答えなさい。

アドレス帳ファイル
class AddressFile
    def initialize(file)
          @original = file
          @meibo = {}
          fo = open(file, "r")    #読み込みモードでファイルを開く。
          lines = fo.readlines    #ファイルの中身を読みこむ
          fo.close           #ファイルを閉じる
          for aLine in lines #ファイルの中身を一行ずつ取り出し
             data = aLine.split
             @meibo[data[0]] = data[1]  
          end    # for
    end # def initializeの終わり
    attr_accessor :meibo
end # class 定義の終わり  

obj = AddressFile.new("address_list.txt")  # アドレス帳を読み込む...インスタンス生成

[クラスの定義の方法]

クラスの定義には、上で示したように、class に続けて 「大文字から始まる名前の」クラス名を書き、いくつかのメソッドを書いて、最後は end で締めます。

クラスを定義するのは、いろいろな部品をもつオブジェクトが使えるようにするためです。 この AddressFile クラスの例では、元のファイル名と、その中身を記憶したハッシュ表を持つオブジェクトを作っています。

ただ、クラスを定義しただけでは、そのようなオブジェクトを使えるようにはなりません。 そのためには、インスタンスオブジェクトを作る必要があります。 インスタンスオブジェクトとは、クラスから生成された一つ一つのオブジェクトのことです。 インスタンスオブジェクトを生成するときは、クラス名(上の場合AddressFile)にnewメソッドを働かせます。

ここで new メソッドを働かせたときに実行されるのがinitializeメソッドです(名前が違うので混乱するかもしれませんが、注意してください)。これは、インスタンス変数に値を設定して、インスタンスオブジェクトの初期化を行うメソッドです。

[インスタンス変数とは]

変数名が@で始まる変数をインスタンス変数と呼びます。 上のAddressFileクラスの場合、@originalと@meiboという2つのインスタンス変数を使用しています。 インスタンス変数には、そのクラスから生成される個々のインスタンスオブジェクトの特徴を表すような値を持たせておきます。 (AddressFileクラスの場合は、オリジナルのファイル名とRuby上でアドレス帳を記憶するハッシュ表。)

[attr_accessorの働き]

インスタンスオブジェクトの内部には、インスタンス変数とその値が保持されています。 そのインスタンス変数の値をそのまま取り出す働きを持つメソッドのことを、アクセスメソッドと呼びます。

attr_accessorは、インスタンス変数に対してアクセスメソッドを提供する簡便なやり方です。attr_accessorに続けて、アクセスしたいインスタンス変数(ただし、この場合は@ではなく : を名前の前につける)をカンマで区切って書きます。 これによって、「インスタンスオブジェクト.インスタンス変数」により、インスタンスオブジェクトのインスタンス変数の値を取り出したり、書き換えたりすることができるようになります。

課題1-2

今度は、この AddressFile クラスに検索プログラム search を付け加えましょう。 searchは、AddressFileクラスのメソッドとして作ることになります。
その場合、アドレス帳ファイルの中身は、すでにコンピュータの中に取り込まれ ハッシュ表であるインスタンス変数 @meiboを使うことができます。

大まかには次のような構造になります。

class AddressFile
   def initialize(file)
      # 課題1-1と同じ
   end
   def search(name)
      #
      # 9月23日の演習に基づき、ここの中身を考える
      #
  end
end   # class

obj = AddressFile.new("address_list.txt")  # アドレス帳を読み込む...インスタンス生成

p obj.search("中京太郎")
p obj.search("中京花子")
p obj.search("中京次郎")

課題1-3

AddressFileクラスに記録されているハッシュの内容に、 新たなデータ(名前とメールアドレス)を追加するメソッドaddをAddressFileクラスのメソッドとして定義しなさい。

大まかには次のような構造になります。

class AddressFile
   def initialize(file)
     #  課題1-1と同じ
   end
   def search(name)
     #
    #  課題1-2のsearchのメソッドの定義 
     #
   end # def of search
   def add(name,address)
      #     
      # 9月23日の演習に基づき、ここの中身を考える
      #
  end  # def of add
end    # class

obj = AddressFile.new("address_list.txt")  # アドレス帳を読み込む...インスタンス生成

#  アドレス帳ファイルの中身を追加する 
obj.add("中京花子", "hanako@chukyo-u.ac.jp")

p obj.search("中京太郎")
p obj.search("中京花子")
p obj.search("中京次郎")

課題1-4

アドレス帳ファイル内の、指定された人物のメールアドレスを書き換える関数updateを AddressFileクラスのメソッドとして定義しなさい。

大まかには次のような構造になります。

class AddressFile
   def initialize(file)
      # 課題1-1と同じ
   end
   #
   #  search, add のメソッドの定義を挿入 
   #
   def update
    #     
      # ここの中身を考える
    # 
  end
end   # class

obj = AddressFile.new("address_list.txt")  # アドレス帳を読み込む...インスタンス生成

 #  アドレス帳ファイルの中身を書き換える 
obj.update("中京太郎","taro@gmail.com")

p obj.search("中京太郎")
p obj.search("中京花子")
p obj.search("中京次郎")
このプログラムの実行の結果、元のファイルの中身が書き変わっていることを確認してください。

課題1-5

AddressFileクラスに記録されているハッシュの内容を、元のファイルに書き出すメソッドsaveをAddressFileクラスのメソッドとして定義しなさい。 これが完成したら、addとupdateメソッドにおいて、記憶内容の変化があればsaveを呼び出すように(つまり変更した結果をファイルに反映するように)修正しなさい。

大まかには次のような構造になります。

class AddressFile
   def initialize(file)
      #  課題1-1と同じ
   end
   #
   #  search, add, updateのメソッドの定義を挿入 
   #
   def save
      #
      # ここの中身を考える
      #
  end
end   # class

obj = AddressFile.new("address_list.txt")  # アドレス帳を読み込む...インスタンス生成

 #  addやupdateなどを用いてアドレス帳ファイルの中身を書き換える 

obj.save     # ファイルに書き出す(addやupdateを書き換えていなければ実行する必要あり)
このプログラムの実行の結果、元のファイルの中身が書き変わっていることを確認してください。

プログラミングIIIのホームに戻る