こんにちは。
本日はRubyメモです。
クラスメソッドとは?
クラスメソッドは、クラスに対して呼ぶメソッドで、
インスタンスを必要としません。
インスタンスメソッドは、インスタンスを必要とします。
本記事では、クラスメソッドの定義の仕方を
- 特異メソッドを1つずつ定義する方法
- 特異クラスを開いてまとめて定義する方法
を記載しています。
特異メソッドを1つずつ定義する方法
self.xxxと記載すると、特定のオブジェクトにxxxという
特異メソッドを1つ追加するという意味になります。
特異メソッドとは、特定のオブジェクト固有のメソッドのことです。
以下の例は、ItemInfoにshow_countとshow_name
という特異メソッドを追加しています。
class ItemInfo # クラス変数 @@count = 0 # コンストラクタ def initialize(id:, name:) @@count += 1 @id = id @name = name end # インスタンスメソッド def show puts "ID = #{@id}, NAME =#{@name}" end # クラスメソッド def self.show_count puts "count = #{@@count}" end def self.show_name puts "ItemInfo" end end
クラスメソッドを呼び出す際は以下のようにします。
ItemInfo.show_count ItemInfo.show_name # count = 1 # ItemInfo
特異クラスを開いてまとめて定義する方法
特異クラスとは、簡単に言うと「クラスオブジェクト専用のメソッド」の入れ物のようなものです。
class << selfでそのクラスオブジェクトの特異クラスを開き、
クラスメソッドをまとめて定義することができます。
先ほどのクラスを特異クラスを使用して書き換えると以下のようになります。
class ItemInfo # クラス変数 @@count = 0 # コンストラクタ def initialize(id:, name:) @@count += 1 @id = id @name = name end # インスタンスメソッド def show puts "ID = #{@id}, NAME =#{@name}" end # 特異クラスを開いてクラスメソッドを定義 class << self def show_count puts "count = #{@@count}" end def show_name puts "ItemInfo" end end end
先ほどは、self.show_count、self.show_nameと定義していましたが
特異クラスを開いて定義する場合、self.は記載不要となります。
呼び出し方法も同じです。
ItemInfo.show_count ItemInfo.show_name # count = 1 # ItemInfo
privateなクラスメソッドを定義する
privateなクラスメソッドとは、外部からの呼び出しができないクラスメソッドです。
こちらも、特異メソッド方式、特異クラス方式でサンプルを作ってみました。
特異メソッドを1つずつ定義する方法
特異メソッド方式の場合は、private_class_methodを使用して
privateにするメソッドを指定します。
以下のコードでは、showメソッドをprivateにしています。
外部から呼び出すとエラーになります。
class ItemInfo def self.show puts "show was called." end def self.show_item puts "show_item was called." show end private_class_method :show end begin ItemInfo.show rescue => e puts "[#{e.class}] #{e.message}" # [NoMethodError] private method 'show' called for class ItemInfo end ItemInfo.show_item # show_item was called. # show was called.
特異クラスを開いてまとめて定義する方法
内容としては特異メソッド方式と同じです。
showメソッドをprivateにして外部から呼び出されるとエラーになります。
特異クラス方式の場合は、特異クラス定義の中で
公開範囲を指定しています。
以下のコードだとshow_itemメソッドはpublic、
showメソッドはprivateを指定しています。
class ItemInfo class << self public def show_item puts "show_item was called." show end private def show puts "show was called." end end end begin ItemInfo.show rescue => e puts "[#{e.class}] #{e.message}" # [NoMethodError] private method 'show' called for class ItemInfo end ItemInfo.show_item #show_item was called. #show was called.
以上です。