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