概要
タイトルの通り、Rubyでクラスメソッドを定義する方法に関する記事です。
動機
元々はクラスメソッド全般に関する記事だったのですが、調べているうちに書き方を色々思いついてしまったのでそちらをメインにすることにしました。
レギュレーション
- 文法要素については1つとして扱う
- メソッドを使うものについてはメソッドの名前ごとに1つとして扱う
- eval系の場合、文字列とブロックは同じ扱いになる
補足
ちゃんとクラスメソッドや特異クラスについて知りたい方は以下の記事をどうぞ!
https://magazine.rubyist.net/articles/0046/0046-SingletonClassForBeginners.html
本編
1. クラス名スタイル
実は利用頻度が少ない気がします。
class C
def C.m
puts 'm'
end
end
2. selfスタイル
最も一般的な書き方な気がします。
class C
def self.m
puts 'm'
end
end
3. 特異クラススタイル
これもよく見かけます。
class C
class << self
def m
puts 'm'
end
end
end
この方法では複数のクラスメソッドを定義したりプライベートなクラスメソッドを定義したりするのが簡単です。
4. extendスタイル
モジュールを使う場合の一般的な方法です。
module M
def m
puts 'm'
end
end
class C
extend M
end
5. includedスタイル
include
されたときにクラスメソッドも定義したい場合に使われます。
module M
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def m
puts 'm'
end
end
end
class C
include M
end
6. define_singleton_methodスタイル
あまり見かけません。:m
の部分を動的にしたいときには使うかも。
class C
define_singleton_method :m do
puts 'm'
end
end
7. instance_evalスタイル
まず見かけません。
class C
end
C.instance_eval do
def m
puts 'm'
end
end
8. singleton_class.class_evalスタイル
まず見かけません。
class C
end
C.singleton_class.class_eval do
def m
puts 'm'
end
end
9. method_missingスタイル
やめましょう。
class Class
def method_missing(meth, *args, &blk)
if name == 'C' && meth == :m
puts 'm'
else
super
end
end
end
10. inheritedとdefine_methodスタイル
define_method
を使うことにこだわってみました。
class Object
def self.inherited(klass)
if klass.name == 'C'
define_method :m do
puts 'm'
end
end
end
end
class C
end
まとめ
クラスメソッドを定義するだけでこんなにたくさん方法があるなんてRubyすごい!
(お仕事では1,2,3を使いましょう。)