LoginSignup
15
1

More than 1 year has passed since last update.

Rubyでクラスメソッドを定義する方法を思いつく限り挙げてみた

Posted at

概要

タイトルの通り、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を使いましょう。)

15
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
1