こんにちは! フリーエンジニアの長瀬です。
Rubyを使ってプログラミングをする際には必須とも言えるべきクラスメソッドの活用。
しかし、そもそもクラスメソッドとは何か、そして具体的にどのような活用方法があるのかについてはご存知でしょうか?
そこで今回は、
【基礎】メソッドの使い方
【基礎】クラスメソッドの使い方
【発展】クラスメソッドをprivateにする方法
【発展】クラスメソッドの継承
などについて解説していきます。
今回はクラスメソッドとは何で、それをどのように定義するのか、そしてクラスメソッドをprivateにする方法や継承についてご紹介しますのでぜひ参考にしてください。
メソッドとは
Rubyにおけるメソッドとは、標準で組み込まれているメソッド(関数)ではなく、ユーザーが独自に定義できる関数のことをメソッドと呼びます。
メソッドを定義することにより、共通した処理をひとまとめにすることができて、メソッドを呼び出すことによって何度でも使用することができます。
Rubyのメソッドは始まりに「def」を指定し、メソッドの終わりに「end」を記述し、その中に実行する処理を記述します。
def メソッド名 実行する処理 end
次項より、メソッドの使い方を詳しく見ていきましょう。
メソッドの使い方
メソッドを定義する方法
それではまずは基本的なメソッドの作成方法から学んでいきましょう。
sayというメソッドを定義してみます。
def say puts "YOLO" #You Only Live Once(人生は一度きり) end say
[実行結果]
YOLO
このように、defを使うことで簡単にメソッドを定義できますね!
sayと入力するだけで、puts “YOLO”が実行されました。
また、メソッドでは引数をあらかじめ設定することもできます。
次にgoodbyeという引数付きのメソッドを定義してみましょう。
def goodbye(name) puts "Goodbye #{name}" end goodbye("World!")
[実行結果]
Goodbye World!
Goodbyeに続き文字列を引数(“World!”)から出力できました。
文字列の中で、メソッドに渡した値を使用したいときには#{}で変数を囲む必要があります。
今回の場合はnameが引数なので、#{name}となっています。
これで基本的なメソッドの定義方法をご理解いただけたかと思います。
defでメソッドを定義する方法についてはこちらの記事にまとめてありますのて、参考にしてみてください。
メソッドの呼び出し
通常、メソッドというものはすべてクラスに定義されているので
(あるクラスを継承した)オブジェクト.メソッド名(第1引数、第2引数、…)){ブロック}
という具合に呼びだすことができます。
例えば、Rubyの文字列オブジェクトのクラスはStringなのでStringクラスにあるメソッドを使用することができます。
name = "Samurai" #文字列オブジェクトnameを定義 "Samurai".class #クラスを確認→Stringクラスだった p name #=> "Samurai" #中身が侍であることを確認 name.replace("Bushi") #Stringクラスからreplaceメソッドを呼び出す(文字列SamuraiをBushiに入れ替える) p name #=> "Bushi" #ちゃんと入れ替わった
この場合、(あるクラスを継承した)オブジェクトはnameで、メソッドはreplaceです。
そして、replaceの第1引数は”Bushi”です。
(あるクラスを継承した)オブジェクト.メソッド名(第1引数、第1引数、…){ブロック} name.replace("Bushi")
通常メソッドを呼び出す場合はこのように、呼び出します。
ですが、トップレベルにメソッドが定義されていた場合はオブジェクトを省略してメソッドを呼び出すことができます。
例えばさきほど紹介したgoobyeメソッドは、オブジェクトを省略して呼び出していますよね?
def goodbye(name) puts "Goodbye #{name}" end goodbye("World!")
また、{ブロック}を渡す場合は例えば配列の場合だと
a = [1,2,3] a.each{|content| p content}
[実行結果]
1 2 3
{|content| p content}の部分がブロックを渡している部分です。
このように、メソッドによってはブロックを渡せる場合もあるので覚えておいてください。
クラスメソッドの基礎知識を知ろう!
クラスメソッドとは
クラスメソッドとは何か、一言で言うと「クラスオブジェクトから実行可能なメソッド」です。
クラスメソッドの対比としてインスタンスメソッドがあります。こちらはクラスに対してではなく、クラスのインスタンス(実体)に対して紐づけられるメソッドです。
また、クラスメソッドはクラスをレシーバとして呼び出すメソッドでもあります。
実際にクラスメソッドとインスタンスメソッドのサンプルコードを見てみましょう。
[クラスメソッド]
class Home def self.pc print("Personal Computer") end end Home.pc
[実行結果]
Personal Computer
[インスタンスメソッド]
class Japanese def nagase print("Nagase Rai") end end instance = Japanese.new instance.nagase
[実行結果]
Nagase Rai
上記コードにありますように、クラスメソッドはクラスをレシーバに呼び出されている一方、インスタンスメソッドはそうなっていません。
クラスメソッドの定義方法
クラスメソッドの定義方法としては4つあります。
selfで定義
これが最も一般的な定義方法です。以下のように、メソッド名の先頭に「self.」をつけます。
class Foo def self.foo "foo" end end
class << self
上記のように、毎回selfをメソッドに付けるのが面倒な場合は一括で行う方法もあります。
class Foo class << self def foo "foo" end def Var "var" end end end
以下の2つはあまり使わない定義方法ではありますが、ご紹介します。
クラス定義スコープの外部で定義(1)
class Foo # クラス定義スコープ end m = 2 Foo.define_singleton_method :echo do |i| m * i end
クラス定義スコープの外で、define_singleton_methodを使ってechoというクラスメソッドを定義しています。
クラス定義スコープの外部で定義(2)
class Foo # クラス定義スコープ end class << Foo def hoge print “hoge” end
こちらもクラス定義スコープ外でhogeクラスメソッドを定義しています。
発展的なクラスメソッドの使い方を見よう!
ここでは、さらに応用したクラスメソッドの使い方について説明します。
クラスメソッドをprivateにする
Rubyのスコープには、
- public
- protected
- private
の3種類があります。
クラスメソッドのスコープをprivateにすることはどのような意味を持つのでしょうか?
クラスメソッドをprivateにすると、クラスメソッドをそのクラス内でしか呼び出せないようになります。
また、private_class_methodを使うことで、クラスやモジュールのクラスメソッドをprivateなメソッドに変更することができます。
以下の例では、newをprivateにすることで外部からのインスタンス化を禁止しています。
class Video private_class_method :new def self.create new end end
クラスメソッドの継承
クラスメソッドの継承についてはこちらの記事で詳しく解説しています。継承をしたい場合はこちらを参照してください。
クラスメソッドを継承させることで、継承したクラスに定義してあるメソッドをそのまま使うことができるようになります。
まとめ
この記事では、クラスメソッドの使い方を解説しました。
- クラスメソッド
- インスタンスメソッドの違い
- クラスの定義方法
などを本記事では紹介しました。
また、private_class_methodでメソッドを指定するとprivateなメソッドに変えられることも学びました。
クラスメソッドを理解することは、オブジェクト志向で作成されているRubyの言語の仕様を理解する上でとても大切になってきます。
なので、しっかりと復習しておいてください。
もしクラスメソッドの使い方について忘れてしまったらこの記事を確認してくださいね!