IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

RubyビギナーのためのStep upコラム

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  OpenStack  システムトラブルシュート 

第11回 クラスインスタンス変数と特異クラス・特異メソッド(2) (中越智哉) 2019年2月

みなさん、こんにちは。
前回、クラスインスタンス変数について取り上げました。そして、このクラスインスタンス変数をより深く知るには、「特異クラス」「特異メソッド」について知る必要がある、ということも書きました。ということで、今回は特異メソッドについてご紹介しましょう。

特異メソッドとは、簡単に言えば特定のインスタンスにのみ属するメソッドのことです。

例えば同じStringクラスの2つのインスタンス(a、b)のうち、インスタンスaのみに、「hello」というメソッドを追加することができます。

これが特異メソッドです。
特異メソッドの定義は、以下のように行います。

def インスタンス.メソッド名
 メソッド内容
end

または、

class << インスタンス
def メソッド名1
メソッド内容
end

def メソッド名2
メソッド内容
end

 ・・・
end

どちらの記述でも同じ結果を得ることが可能ですが、後者の場合は複数の特異メソッドを同時に定義する場合に、メソッド名の前につけるインスタンス名を省くことができ、メンテナンス性にメリットがあります。

ここでは、特異メソッドの定義は1つだけなので、前者の形式を使ってみます(ファイル名はtkimethod1.rbとしました)。

fig01

これを実行すると、9行目の実行で例外(NoMethodError)が発生します。

fig02

これにより、特異メソッドがインスタンスaにだけ属するメソッドであることがわかると思います。

さて、この特異メソッドの定義を見ていて、何か既視感を覚えた方はいらっしゃらないでしょうか。そうなのです。この、特異メソッドの定義方法は、いわゆるクラスメソッドを定義するときの方法と、全く同じなのですね。

上記の例を変更して、インスタンスaに対する特異メソッド定義部分を、クラスメソッド定義の形式に変更してみます。クラスメソッドは通常のインスタンスが不要なため、変数a、bも不要ですし、呼び出しは「クラス名」.「メソッド名」となります。

fig03

当然ですが、問題なく表示できました。
ここまでくると、もう、皆さんもお気づきかもしれませんが、実はクラスメソッドも特異メソッドなのです。

ただしクラスメソッドは、あるインスタンスではなく、クラスインスタンスにのみ属する特異メソッドになります。

つまりクラスメソッドの実行というのは、文法的に見るとそれほど特別なメソッドではなく、単にクラスインスタンスの特異メソッドを実行しているだけだったのですね。

ここで、前回のコラムの話題であるクラスインスタンス変数に戻ってみます。クラスインスタンス変数は、クラスインスタンスにのみ属するインスタンス変数でした。

クラスメソッドはクラスインスタンスにのみ属するメソッドなので、下記のプログラムのように、クラスメソッドの中からであれば、クラスインスタンス変数にアクセスできることになります。

fig04

特異メソッドが理解できると、クラスインスタンス変数の動作の様子も納得がいくのではないでしょうか?

ですが、そうすると、今度はこんな疑問が浮かばないでしょうか。
「インスタンスに対する特異メソッドは、一体どこに定義されるのか?」
「特異メソッドを持つようなクラスそのものはどこにどうやって定義されるのか?」

次回は、その謎を解くための鍵である「特異クラス」について取り上げます。
どうぞお楽しみに。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  OpenStack  システムトラブルシュート