クラスを作る::Ruby

### 例 : HelloWorldクラス
class HelloWorld # class文
  Version = "1.0" # 定数の定義

  def initialize(myname="[[Ruby]]")
    @name = myname # インスタンス変数の初期化
  end

  def hello # インスタンスメソッド
    print "Hello, world. I am ", @name, ".\n"
  end
end

bob = HelloWorld.new("Bob")
alice = HelloWorld.new("Alice")
ruby = HelloWorld.new

bob.hello

8.2.1 class文


一般形
class クラス名
  クラスの定義
end

8.2.2 initializeメソッド


class文の中でメソッドを定義すると,そのクラスのインスタンスメソッドとなる。
initializeというメソッドは,newメソッドでオブジェクトを生成すると,呼び出される。
要するに初期化

8.2.3 インスタンス変数とインスタンスメソッド


@nameのような@で始まる変数インスタンス変数という。
インスタンス変数は,同じインスタンス内であればメソッド定義を越えて
その値を参照したり変更したりできる。
初期化されていないインスタンス変数を参照するとnilが返される。

インスタンス変数は,インスタンスメソッドから参照できる。

8.2.4 アクセスメソッド


オブジェクトの外部からインスタンス変数を直接参照したり,
インスタンス変数に代入したりできない。
オブジェクトの内部の情報にアクセスするためのメソッドが,アクセスメソッド

### アクセスするメソッドを追加した例
class HelloWorld
  ...

  # @nameを参照する
  def name
    return @name
  end

  # @nameを変更する
  def name=(value)
    @name = value
  end
end
最初のメソッドnameは,@nameの値を返すだけ。
p bob.name # => "Bob"

2番目のメソッドname=は,
bob.name = "foo"
p bob.name # => "foo"

これらを簡単に定義するために用意されているのは下記。

アクセスメソッドの定義

定義 意味
attr_reader :name 参照のみを可能にする
attr_writter :name 変更のみを可能にする
attr_accessor :name 参照と変更の両方を可能にする(上記2つを定義する)

インスタンスを設定するメソッドをセッター(setter)
参照するメソッドをゲッター(getter)
これらを合わせてアクセスメソッド(アクセサ)という。

8.2.5 特別な変数self

インスタンスメソッドの中で,メソッドのレシーバ自身(メソッドを読んだオブジェクトのこと??)を
参照するには,selfという変数を使う。

アクセスメソッドの例で作成したnameメソッドを,
別のインスタンスメソッドから呼ぶことを考える。
### nameメソッドについて
class HelloWorld
  attr_accessor :name
    ...
  def greet
    p self.name
  end
end
...
「self.name」はgreetメソッドを読んだときのレシーバを参照している。

name=メソッドのように,「=」で終わるメソッドを呼び出す場合は注意が必要。
def test_name
  name = "Ruby"  # ローカル変数への代入
  self.name = "Ruby"  # name=メソッドの呼び出し
end
単にnameと書くと,ローカル変数が定義される。

8.2.6 クラスメソッド

クラスそのものをレシーバとするメソッド。
def クラス名.メソッド名
  ...
end
クラス定義の中のselfは,
そのクラスオブジェクト自身を参照するから,
def クラス名.メソッド名
  ...
end
と定義しても同じ意味。

クラス定義のなかにインスタンスメソッドの形式で定義する書き方。
class << クラス名
  ...
end
複数のクラスメソッド書く際に便利。
class HelloWorld
  class << HelloWorld  # class << self でもよい
    def hello(name)
      print name, " said hello.\n"
    end
  end
end
HelloWorld.hello("John")  # => John said hello.

8.2.7 定数

class文の中では定数を定義できる。
## 例
Version = 1.0
::で参照できる。
p HelloWorld::Version  #  => 1.0

8.2.8 クラス変数

@@で始まる変数。
そのクラスの全てのインスタンスで共有できる。
定数との違いは,何度でも値を変更できること。
定数のように参照するには,アクセスメソッドを自分で用意しなければならない。
### HelloWorldクラスを修正して,helloメソッドが呼ばれた回数を集計した
class HelloCount
  @@count = 0  # helloメソッドの呼び出し回数
   
  def HelloCount.count  # 呼び出し回数を参照するためのクラスメソッド
    @@count
  end
  
  def initialize(myname="Ruby")
    @name = myname
  end
  
  def hello
    @@count += 1  # 呼び出し回数を数える
    print "Hello, world. i am ", @name, ".\n"
  end
end

8.2.9 クラスを拡張する

すでに定義されているクラスにメソッドを追加できる。
### Stringクラスに,文字列中の単語数を数えるメソッドを追加する
class String
  def count_word
    ary = self.split(/\s+/)  #               
    return ary.size  #               
  end
end

str = "Just Another Ruby Newbie"
p str.count_word
この機能の実現には,count_wordメソッドの中で,
count_wordを呼び出したオブジェクト(レシーバ)(selfのこと)を参照しなければならない。



最終更新:2011年10月13日 15:53