1から始めるRuby(その3)
1から始めるRuby(その2)の続きです。
クラスメソッド定義(続き)
bonjourメソッド内でselfを使うことでこのメソッドがそれぞれのクラスでの呼び出しに対し、適切に応答するようになった。
しかしできればbonjourメソッドはFixnum専用のものにして、他のクラスでは呼び出せないようにしたい。Classクラスはすべてのクラスのクラスだったから、そこに定義したbonjourメソッドはすべてのクラスで呼び出せるようになってしまった。仮にFixnumのためだけのクラスがあれば、そこにbonjourメソッドを定義して問題は解決しそうである。
期待通りRubyにはそのようなクラスが存在する。しかしなぜかひっそりと..
早速このクラスを使って目的を果たそう。
>> class << Fixnum
>> def bonjour
>> "Bonjour from Fixnum with love!"
>> end
>> end
=> nil
>> Fixnum.bonjour
=> "Bonjour from Fixnum with love!"
>> String.bonjour
NoMethodError: undefined method `bonjour' for String:Class
>> Array.bonjour
NoMethodError: undefined method `bonjour' for Array:Class
>> Class.bonjour
NoMethodError: undefined method `bonjour' for Class:Class
class « Fixnum という構文はFixnumオブジェクト専用の名無しのクラスを定義する。この構文を見慣れないRuby使いもきっといるだろう。Rubyにひっそりと存在するものだから、その呼び方すら確定していない。ある人はSingletonクラスといい、ある人はEigenクラスといい、またある人は特異クラスという1。私は是非ともステルスクラスと呼びたいが。
実はこの構文には別の書き方が3種ある。そしてこちらの書き方のほうが広く知られている。
class Fixnum
class << self # Fixnumクラス定義の中でselfを使って
def bonjour
"Bonjour from Fixnum with love!"
end
end
end
def Fixnum.bonjour # メソッド定義でFixnumを前置して
"Bonjour from Fixnum with love!"
end
class Fixnum
def self.bonjour # Fixnumクラス内のメソッド定義でselfを前置して
"Bonjour from Fixnum with love!"
end
end
最初の構文は元の構文をFixnumクラス定義内に配置したものだ。Fixnumクラス内でselfはFixnumを返す。次の構文はメソッド定義をするときにその適用対象オブジェクト(ここではFixnum)を限定するやり方だ。最後の構文はこのメソッド式構文をクラス定義内に配置したものだ。
なぜ同じ事をやるのに4種もの書き方があるのかというと、RubyはPerlの流れを汲むTMTOWTDIの言語だからだ。
TMTOWTDIを最初見たとき私は、「TiMe TO WheTher Die or Ill」の略だと思ったのだが、正しくは、
There’s More Than One Way To Do It (やり方はいくらあってもええじゃないか)
の略だそうである。長い割には面白くない答えだったので、別の答えを用意した。
/Today’s (Mon Tue) Or (Wed Thu) Day/I
(続く?)
- ruby1.9ではsingletonを使っているようです. class<<1;end ↩
blog comments powered by Disqus