Rubyでは全てのデータはオブジェクトで、何らかのクラスのインスタンスです。

これは、C++やJavaなどは数値は数値型という「型」ですが、Rubyでは数値クラスのインスタンスであるということを意味します。

例えば、以下のスクリプトは10というIntegerクラスのオブジェクトのdowntoというインスタンスメソッドを呼び出し、10から1までを順番に標準出力へ出力します。

 10.downto(1) {|i|
puts i
}

クラスを定義する

class文を使用することで新しくクラスを定義することができます。以下に構文と例を示します。

 ■構文 
 class クラス名 [< スーパークラス]
   文
 end
 
 ■例
 class MyInteger < Integer
  # 略
 end

クラス名は定数(大文字で始まっている)である必要があります。

メソッドを定義するには

メソッドはdef文で定義することができます。以下に構文と例を示します。

 ■構文
 def メソッド名[`(' [arg ['=' default]] ... [`,' `*' arg] [',' '&' arg]`)']
   文
 end
 
 ■例
 def square(x)
   x * x
 end

オブジェクトの初期化を行う

オブジェクトの生成は各クラスのnewメソッドで行いますが、newメソッドは新しいオブジェクトを生成後、そのオブジェクトのinitializeメソッドを呼び出します。

オブジェクトの初期化はnewメソッドを再定義するのではなく、initializeメソッドを再定義することが推奨されています。initializeメソッドは自動的に可視性がプライベートになります。

 class SampleClass
def initialize(num)
@num = num
end

def getnum
@num
end
end

o = SampleClass.new(10) p o.getnum #=> 10

インスタンス変数・クラス変数を定義する

インスタンス変数は主にオブジェクトの状態など、インスタンスごとに異なるデータを保持するために使用されます。@で始まる変数名を付与することでインスタンス変数になります。

 class SampleClass
def initialize
@var = 0
end

def getvalue
@var
end

def setvalue(value)
@var = value
end
end

o = SampleClass.new
o1 = SampleClass.new

o.setvalue(100)
o1.setvalue(200)

p o.getvalue #=> 100
p o1.getvalue #=> 200

クラス変数は主にクラスのインスタンスやサブクラスのインスタンス間で共通の情報を保持するために使用されます。

@@で始まる変数名を付与することでクラス変数になります。クラス変数はメソッド定義の外で代入される必要があります。

 class SampleClass
@@cvar = 1

def getvalue
@@cvar
end

def setvalue(n)
@@cvar = n
end
end

class SampleClass2 < SampleClass ;end

o1 = SampleClass.new
o2 = SampleClass2.new

p o1.getvalue #=> 1
o1.setvalue(100)
p o2.getvalue #=> 100 # o1.setvalue で値を設定したが、o2の@@cvarに反映されている

インスタンス変数へアクセスするメソッドを簡単に定義する

attr_readerメソッド、attr_writerメソッド、attr_accessorメソッドを使うとインスタンス変数へアクセスするためのメソッドが自動的に定義されます。

メソッド名はそのインスタンス変数と同一の名称で定義されます。attr_readerメソッドは読み出しメソッドのみ、attr_writerメソッドは代入メソッドのみ、attr_accessorメソッドは両方のメソッドが定義されます。

 class SampleClass
def initialize
@a = 0
@b = 0
@c = 0
end

attr_accessor :a, :b, :c
end

o = SampleClass.new
o.a = 10
o.b = 20
o.c = 30

p o.a #=> 10
p o.b #=> 20
p o.c #=> 30

メソッドの仮引数でデフォルト値を指定する

メソッドの仮引数に式を与えることでメソッドを呼び出すときに引数が与えられなかった場合に、その式が評価され使用されます。

 def say(message = 1)
case message
when 1
puts "Good moring!"
when 2
puts "Good day!"
when 3
puts "Good night!"
end
end

say() #=> "Good moring!"
say(1) #=> "Good moring!"
say(3) #=> "Good night!"

引数の数が可変なメソッドを定義する

仮引数の数が可変なメソッドを定義するには、最後の仮引数の直前に*を指定します。そうすると残りの実引数は配列としてこの引数に格納されます。

 def order(custid, *products)
print "custid #{custid}:"
products.each {|p| print " #{p}"}
end

order(1, 1000, 1001, 1002) #=> custid 1: 1000 1001 1002
order(2, 1000, 1003) #=> custid 2: 1000 1003

メソッドの引数にブロックを渡す

Rubyではコード自体をメソッド呼び出し時に渡す機能があります。

メソッド定義内でyieldを使うことで、呼び出し側から渡されたコード(ブロック)を実行することができます。

 def func(x, y)
x + yield(y, 2)
end

p func(4, 3){|a, b| a * b} #=> 4 + 3 * 2 #=> 10
p func(4, 3){|a, b| a - b} #=> 4 + 3 - 2 #=> 5

yieldを使わずにメソッド定義で仮引数の前に&をつけることで、メソッドに与えられているブロックを手続きオブジェクト(Procクラスのインスタンス)としてこの引数に格納することもできます。

手続きオブジェクトを実行するにはProc#self、Proc#callメソッドを使用します。

 def func(x, y, &block)
x + block.call(y, 2)
end

p func(4, 3){|a, b| a * b} #=> 4 + 3 * 2 #=> 10
p func(4, 3){|a, b| a - b} #=> 4 + 3 - 2 #=> 5

クラスメソッドを定義する

クラスメソッドは主にインスタンスの内容に依存しない処理を記述するのに用いられ、オブジェクトを生成しなくても呼び出すことができます。

以下の例はSampleClass?::helloというクラスメソッドと、SampleClass?#byeというインスタンスメソッドを定義しています。

 class SampleClass
def SampleClass.hello
"Hello, World!"
end

def bye
"Bye!"
end
end

p SampleClass.hello #=> "Hello, World!"
p SampleClass::hello #=> "Hello, World!"
p SampleClass.bye #=> NameError

メソッドの戻り値を設定する

メソッドの戻り値はreturn文で指定することもできますが、return文が無いか実効されなかった場合、最後に評価した式の値がメソッドの戻り値になります。

 def func1
return 1
end

def func2
1
end

p func1 #=> 1
p func2 #=> 1

メソッドの可視性を定義する

Rubyのメソッドはpublic、private、protectedの3つの呼び出し制限をかけることができます。以下にそれぞれの特徴を示します。

public
制限なしに呼び出すことができる
private
同じクラスのインスタンスだけから呼び出すことができる
protected
そのメソッドが定義されたクラスおよびその下位クラスのインスタンスからしか呼び出せない
 class SampleClass
def hoge # public (default)
end

def boke
end
private :boke # private

def auau
end
protected :auau # proctected
end

o = SampleClass.new
o.hoge
o.boke #=> NameError
o.auau #=> NameError

スーパークラスのメソッドを呼び出す

superを使うと同名のスーパークラスのメソッドを呼び出すことができます。引数を省略するとメソッドの引数がそのまま渡されます。

 ■構文
 super([式 [,式...]])
 super 式[,式...]
 super
 
 ■例
 def hoge
   super # スーパークラスのhogeメソッドを呼び出す
   # 略
 end