2-5-3 self メソッドが属しているインスタンスをselfという名前の擬似変数で参照できる。
他の言語で言うとthisにあたる。


In [1]:
class Ruler
    attr_accessor :length
    
    def display_length
        # Ruler#length の戻り値を出力している
        puts length
    end
end

ruler = Ruler.new
ruler.length = 30

ruler.display_length


30

レシーバを省略できる場合には省略するのが普通です。
ただし、Ruler#length=のようなメソッド呼び出しのselfは省略できません。


In [4]:
class Ruler
    attr_accessor :length
    
    def set_default_length
        # length = 30ではメソッドは呼び出されず、lengthという名前のローカル変数が定義される
        self.length = 30
    end
end

ruler = Ruler.new
ruler.set_default_length

ruler.length


Out[4]:
30

2-5-4 初期化
Rubyでの初期化はinitializeという名前のメソッドを定義します。
他の言語ではコンストラクタと呼ばれているものに相当します。


In [5]:
class Ruler
    attr_accessor :length
    
    def initialize(length)
        @length = length
    end
end

ruler = Ruler.new(30)
ruler.length


Out[5]:
30

上記の例では、initializeでインスタンス変数@lengthを設定しています。
newの引数に渡した値は、initializeの仮引数として受け取ることができます。

2-5-5 クラスメソッド
すべての値はオブジェクトとして扱われます。
クラスも例外ではなく、クラスに対してもメソッド呼び出しができます。
クラスに対して呼び出すことのできるメソッドをクラスメソッドと言います。

クラスメソッドは、メソッド名の前にself.をつけて定義します。


In [12]:
class Ruler2
    attr_accessor :length
    
    def self.pair
        [Ruler2.new, Ruler2.new]
    end
end

Ruler2.pair


Out[12]:
[#<Ruler2:0x007fbb9bb4d080>, #<Ruler2:0x007fbb9bb4d058>]

クラスメソッドの中でのselfは、そのメソッドが属するクラスになります。
Ruler2.pairの中でnewのレシーバを省略して[new, new]と記述することもできます。

2-5-6 クラス変数
クラスとそのインスタンスをスコープとした変数をクラス変数と言います。
クラス変数は「@@cvar」のように、@2つからはじまる名前で表記します。


In [14]:
class MyClass
    @@cvar = 'Hello, My class variable!'
    
    def cvar_in_method
        puts @@cvar
    end
    
    def self.cvar_in_class_method
        puts @@cvar
    end
end

my_object = MyClass.new

my_object.cvar_in_method
MyClass.cvar_in_class_method


Hello, My class variable!
Hello, My class variable!

2-5-7 継承
Rubyは単一継承をサポートしています。2つのクラスが継承関係にあるとき、継承されたほうをスーパークラス、継承したほうをサブクラスと言います。
クラスを継承するには、クラス定義の際、以下のように「<」でスーパークラスを指定します。

class サブクラス名 < スーパークラス名 end


In [16]:
# スーパークラス
class Parent
    def hello
        puts 'Hello, Parent class!!'
    end
end

# Parentを継承したChild
class Child < Parent
    def hi
        puts 'Hello, Child class!'
    end
end

child = Child.new
child.hello
child.hi


Hello, Parent class!!
Hello, Child class!

In [21]:
# スーパークラス
class Parent2
    def hello
        puts 'Hello, Parent2 class!!'
    end
end

# Parentを継承したChild
class Child2 < Parent2
    def hello
        # superは、Parent#hello が呼び出される
        super
        
        puts 'Hello, Child2 class!!!!!'
    end
    
    def hi
        puts 'Hello, Child2 class!'
    end
end

child2 = Child2.new
child2.hello
child2.hi


Hello, Parent2 class!!
Hello, Child2 class!!!!!
Hello, Child2 class!

クラス定義時にスーパークラスを指定しない場合には、Objectクラスを継承したクラスが定義されます。何も継承しないクラスを定義することはできません。


In [26]:
class Whatever
end

Whatever.superclass


Out[26]:
Object

2-6 モジュール
Rubyにはモジュールと呼ばれるクラスとよく似たものがあります。 モジュールの特徴を一言で説明すると「インスタンス化できないクラスのようなもの」ということができます。

module モジュール名 end


In [28]:
module Brainfsck
    class Parser
        # 何かの処理
    end
end

module Whitespace2
    class Parser
        # 何かの処理2
    end
end

# ::を用いて参照する
Brainfsck::Parser
Whitespace2::Parser


Out[28]:
Whitespace2::Parser

モジュール定義の中でもメソッド定義することができる。
クラスに定義したメソッドとは異なる用途に使われます。

・あるクラスのインスタンスメソッドとして取り込む
・あるオブジェクトのメソッドとして取り込む
・モジュール関数として使う


In [39]:
module Whitespace3
    class Parser3
        # 何かの処理2
    end
end

class Whitespace3::Parser4
    # このクラス名はできない
end

p Whitespace3::Parser4.class


Class
Out[39]:
Class