Ruby/クラス

最終更新: 2010-01-13 (水) 16:42:29 (2632d)

このページの内容は http://yakinikunotare.boo.jp/orebase2/ruby/class に移動しました

目次 Edit

クラスの概念 Edit

RubyのクラスはClassクラスのインスタンスとして存在する。
つまりクラスはオブジェクト。
オブジェクトとしてのクラスにとってClassクラスはklassとなる

そしてクラス名は定数ということになる。
つまりスコープに定数がばら撒かれていて、そこにクラスオブジェクトが入っていると思っていい

なので

class Hoge
end

この記法はクラスオブジェクトリテラル+定数設定ということになる。

クラスを作る Edit

class Hoge
    def hoge
        print "ほげ"
    end

    def piyo
        print "ぴよ"
    end
end
class クラス名
    def メソッド名
        #処理内容
    end
end

クラスメソッド(静的メソッド)を作る Edit

クラスメソッドはselfかクラス名をメソッドの頭につけることによって作れる。
通常はクラス名変更のリファクタを考慮するからselfを使う

class Hoge
  def Hoge.hoge
    print "ほげ"
  end

  def self.piyo
    print "ぴよ"
  end
end

つまりselfはそのオブジェクト内ではオブジェクト自身を指すことになる。なんでそうなるかといえば、RubyにとってclassはClassクラスのインスタンスになる。class Hoge〜の記述はclass宣言ではなく、classインスタンスリテラルと捉えられる。

なのでclass 〜 end中のselfはClassクラスのインスタンス自身を指すことになり、クラスメソッドにselfをつけるのはそういう意味なのだ。

なのでそのクラスメソッド内部のselfもクラス自身を表すことになる

class Hoge
  def self.piyo
    print "ぴよ"
  end

  def self.fuga
    print self.piyo
    print "ふが"
  end
end

Hoge.fuga //=>"ぴよふが"

逆にインスタンスのメソッドを呼び出すときは内部のselfはオブジェクト=インスタンス自身となる。

クラス名の命名規約 Edit

Rubyのクラス名の命名規約はJavaと同じでパスカル方式

HogePiyo

ファイル名の命名規約 Edit

全部小文字のハイフン繋ぎ。Rubyは複数のクラスを1個のファイルに記述できるが、そのなかでもインターフェースとなる主要なクラスをファイル名の元ネタとして使うのが一般的

hoge-piyo.rb

コンストラクタ Edit

コンストラクタは特別なメソッドinitializeで定義する。

class Hoge
    def initialize(a)
    end
end

Rubyには型が無いのでJavaのような引数の数と型による多態性は内部で自分で実装すれば実現できる。

メソッドを動的に追加する Edit

インスタンスメソッド Edit

RubyはJavaとかと違ってコード動作中で動的にクラスにメソッドを追加できる

class Hoge
  def hoge
    print "ほげ"
  end
end

if(true)
  class Hoge
    def piyo
      print "ぴよ"
    end
  end
end

aaa = Hoge.new()
aaa.piyo()    #=> "ぴよ"

こんな風に既に定義されているクラスでもう一度定義すると再定義ではなくて追加になる

オブジェクトの作られたタイミングと追加したメソッドの実行には関係が無い
だから

class Hoge
  def hoge
      print "ほげ"
  end
end
aaa = Hoge.new()

if(true)
  class Hoge
    def piyo
      print "ぴよ"
    end
  end
end

aaa.piyo()    #=> "ぴよ"

これもOK。

つまりメソッドは実行時にklassポインタをたどって検索されるという話

クラスメソッド Edit

クラスメソッドを後付で追加するにはクラスオブジェクト自体の特異メソッドとして追加すれば実現できる。

class Hoge
end

class <<Hoge
  def hello
    puts "hello"
  end
end

Hoge.hello

メソッドを動的に特定のオブジェクトのみに追加する(特異メソッド) Edit

Javascriptのように特定のオブジェクトのみにメソッドを追加できる

class Hoge
    def hoge
        print "ほげ"
    end
end
aaa = Hoge.new()

#ここで追加
def aaa.piyo
    print "ぴよ"
end

aaa.piyo()    #=> "ぴよ"

bbb = Hoge.new()
bbb.piyo()   #=>エラー

特定オブジェクトのみにMixinする Edit

特異メソッド的な機能をmoduleを使ってやることもできる
これにはextendメソッドを使う

#モジュール
module Piyo
    def piyo
        print "ぴよ"
    end
end

#クラス
class Hoge
    def hoge
        print "ほげ"
    end
end

a = Hoge.new()

#ここでmix-in
a.extend Piyo
a.piyo()    #=>"ぴよ"

b = Hoge.new()
b.piyo()    #=>エラー

メソッドのオーバーロード Edit

Rubyではメソッド名同一の引数によるシグネチャ違いをたくさん定義することができない
その代わりにオプション引数とかrest引数というものを駆使してやると同じようなことができる

つまりメソッドの引数は一番細かい粒度で作っておき、プリセットの値をオプションで埋めておくことで対応

class Hoge
    def hoge(a, b=1, c=2)
        #何か処理
    end
end

メソッドの再定義 Edit

インスタンスメソッド Edit

同名のメソッドでメソッド追加してやるとメソッドの再定義になる

class Hoge
  def hello1
    puts "hello1"
  end
end

class Hoge
  def hello1
    puts "hello1+"
  end
end

Hoge.new.hello1 #=>"hello1+"

再定義したいんだけど、前の定義も利用したい場合は、このように既存のメソッドに別名をつけておいてポインタを掴んでおく。
そうした上で既存の名前を上書きする。

class Hoge
  def hello1
    puts "hello1"
  end
end

class Hoge
  def hello1_plus
    hello1_inner   #既存のメソッドを別名を利用して実行
    puts "+"
  end
  alias_method :hello1_inner, :hello1
  alias_method :hello1, :hello1_plus  #既存のメソッドを上書き
end

Hoge.new.hello1

つまりこれは実行タイミングと定義タイミング、上書きタイミングをずらすためにaliasを使っている。

クラスメソッド Edit

こちらもインスタンスメソッドと同様に同名でもう一度定義させれば再定義になる。

class Hoge
  def self.hello1
    puts "hello1"
  end
end

class Hoge
  def self.hello1
    puts "hello1+"
  end
end

Hoge.hello1 #=> "hello1+"

既存のクラスメソッド利用したい場合は特異メソッドの記法を用いて内部に「オブジェクト空間」のようなものを作ってそれに対して操作をかける事によって文法的に整合性をとりつつ、既存のものを利用しつつ上書きできる。

class Hoge
  def self.hello1
    puts "hello1"
  end
end

class Hoge
  class <<self
    def hello1_plus
      hello1_inner
      puts "+"
    end
    alias_method :hello1_inner, :hello1
    alias_method :hello1, :hello1_plus
  end
end

Hoge.hello1

このことから特異メソッドの「<<」の記法は他の言語で言う「with」のような効果があることがわかる。

Mixin(メソッドだけ単独で借りてくる) Edit

Rubyはメソッドの実装だけ単独で借りてくることができるMixinという機能がある
Ruby/Mix-in参照

オブジェクト自身(JavaとかC++でのthis) Edit

Rubyではselfキーワードであらわす

演算子の定義 Edit

Rubyでは演算子自体もメソッド呼び出しとして実装されている。
だがこいつのうまい使い方がいまいちわからんwww

二項演算子 Edit

class Hoge
    def +(a)
        print a
    end
end

a = Hoge.new()
a + "がおー"

単項演算子 Edit

class Hoge
    attr_accessor :aaa
    def +@
        print self.aaa
    end
end

a = Hoge.new()
a.aaa = "がおー"
+a

クラス定数 Edit

クラス定数を作る Edit

クラス定数は慣例的にスネークケースのアッパーで書く。
class記述の直下にバンと書けばOK

class Hoge
  PIYO = "1"
end

クラス定数へのアクセス Edit

外部からのアクセス
コロン2個のスコープ解決を使って書く

PIYO = "2"
class Hoge
  PIYO = "1"
end
p Hoge::PIYO #=>"1"

クラスメソッドからのアクセスは何もつけずにOK・・・何かつけちゃだめ

PIYO = "2"
class Hoge
  PIYO = "1"
  def self.piyo
    p PIYO
  end
end
Hoge.piyo #=>"1"

インスタンスメソッドは同じく何もつけずにOK・・・何かつけちゃだめ

PIYO = "2"
class Hoge
  PIYO = "1"
  def piyo
    p PIYO
  end
end
Hoge.new.piyo #=>"1"

関連ページ Edit

Ruby/継承?

参考サイト Edit

コメント Edit


タグ Edit

Tag: クラス Ruby 文法 命名規約 移動済み

リロード   new Edit 凍結 差分 Upload 複製 名前変更   Home Page list Word Search Recent Update バックアップ Referer   Help   最終更新のRSS
Last-modified: 2010-01-13 (水) 16:42:29 (2632d)