7-7-2 特別なクラスやメソッドの存在を確認しよう

クラスを別の書き方で定義する

以下のようにプログラムを記述し、ファイル名をspecial_classes1.rbで保存します。

# クラスを別の書き方で定義する
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

# Specialclassのインスタンスを生成
instance = SpecialClass.new

# インスタンスメソッド呼び出し
instance.call_instance_method

クラスを別の書き方で定義したプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に"called instance_method."と表示されます。

$ ruby special_classes1.rb
"called instance_method."

名前のないクラス(無名クラス)を定義する

以下のようにプログラムを記述し、ファイル名をspecial_classes2.rbで保存します。

# 名前のないクラス(無名クラス)を定義する
class_object = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

# 無名クラスでもオブジェクト生成できる
instance = class_object.new

# インスタンスメソッドも呼び出せる
instance.call_instance_method

# クラスを表示するとClassクラスである
p instance.class

# クラス名はnil
p instance.class.name

名前のないクラス(無名クラス)を定義したプログラムを実行する

コマンドライン上で保存したプログラムを実行します。

実行結果に"called instance_method."と表示された後、Classクラスのオブジェクトが表示されます。最後にnilと表示されます。

$ ruby special_classes2.rb
"called instance_method."
#<Class:0x007fb8e5099368>
nil

クラス定義の外側からクラスメソッドを定義する

以下のようにプログラムを記述し、ファイル名をspecial_classes3.rbで保存します。

# クラス定義の外側からクラスメソッドを定義する
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

# クラスの外側からクラスメソッドを定義できる
def SpecialClass.call_class_method
  p 'called class_method.'
end

instance = SpecialClass.new
instance.call_instance_method

# 定義したクラスメソッドが呼び出せる
SpecialClass.call_class_method

クラス定義の外側からクラスメソッドを定義したプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に"called instance_method.""called class_method."と表示されます。

$ ruby special_classes3.rb
"called instance_method."
"called class_method."

これまでの書き方でメソッドを再定義する

以下のようにプログラムを記述し、ファイル名をspecial_classes4.rbで保存します。

# インスタンスメソッドとクラスメソッドを
# これまでの書き方で再定義する
class SpecialClass
  def call_instance_method
    p 'called instance_method.'
  end

  def self.call_class_method
    p 'called class_method.'
  end
end

# 実行結果は同じ
instance = SpecialClass.new
instance.call_instance_method

SpecialClass.call_class_method

class宣言を使ったプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に"called instance_method.""called class_method."と表示されます。

$ ruby special_classes4.rb
"called instance_method."
"called class_method."

インスタンスに直接メソッドを定義する

以下のようにプログラムを記述し、ファイル名をspecial_classes5.rbで保存します。

# インスタンスに直接メソッドを定義する
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

instance = SpecialClass.new
instance.call_instance_method

# インスタンスにメソッドを定義できる
def instance.call_singleton_method
  p 'called singleton_method.'
end

# インスタンスに定義したメソッドを呼び出せる
instance.call_singleton_method

インスタンスに直接メソッドを定義したプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に"called instance_method.""called singleton_method."と表示されます。

$ ruby special_classes5.rb
"called instance_method."
"called singleton_method."

インスタンスに直接メソッドを定義した場合のスコープを確認する

以下のようにプログラムを記述し、ファイル名をspecial_classes6.rbで保存します。

# インスタンスに定義したメソッドは
# インスタンスに閉じたスコープのみ使用可能
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

instance = SpecialClass.new
instance.call_instance_method

def instance.call_singleton_method
  p 'called singleton_method.'
end

instance.call_singleton_method

# 別のインスタンスを生成
other_instance = SpecialClass.new

# インスタンスメソッドは呼び出せる
other_instance.call_instance_method

# このインスタンスにはメソッドが定義されていないのでエラー
other_instance.call_singleton_method

インスタンスに直接メソッドを定義した場合のスコープを確認するプログラムを実行する

コマンドライン上で保存したプログラムを実行します。

実行結果に"called instance_method.""called singleton_method.""called instance_method."と表示された後、call_singleton_methodメソッドが見つからないことを示すNoMethodErrorが表示されます。

$ ruby special_classes6.rb
"called instance_method."
"called singleton_method."
"called instance_method."
special_classes6.rb:25:in `<main>': undefined method `call_singleton_method' for #<SpecialClass:0x007fc2f9a08b88> (NoMethodError)
Did you mean?  call_instance_method

インスタンスに定義したメソッドのクラスを確認する

以下のようにプログラムを記述し、ファイル名をspecial_classes7.rbで保存します。

# インスタンスに定義したメソッドのクラスを確認するプログラムを保存する
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

instance = SpecialClass.new

def instance.call_singleton_method
  p 'called singleton_method.'
end

instance.call_singleton_method

# インスタンスのクラス
p instance.class

# インスタンスの特別なクラス(特異クラス)
p instance.singleton_class

インスタンスに定義したメソッドのクラスを確認するプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果に"called singleton_method."SpecialClassと表示された後、特異クラスが表示されます。

$ ruby special_classes7.rb
"called singleton_method."
SpecialClass
#<Class:#<SpecialClass:0x007f8c8091cd78>>

特異メソッドの定義場所を確認するプログラムを保存する

以下のようにプログラムを記述し、ファイル名をspecial_classes8.rbで保存します。

# 特異メソッドの定義場所を確認する
SpecialClass = Class.new do
  def call_instance_method
    p 'called instance_method.'
  end
end

instance = SpecialClass.new

def instance.call_singleton_method
  p 'called singleton_method.'
end

# インスタンスメソッドはSpecialclassに定義済
p instance.class.method_defined?(:call_instance_method)

# 特異メソッドはSpecialclassには未定義
p instance.class.method_defined?(:call_singleton_method)

# インスタンスメソッドは特異クラスに定義済
p instance.singleton_class.method_defined?(:call_instance_method)

# 特異メソッドは特異クラスに定義されている
p instance.singleton_class.method_defined?(:call_singleton_method)

特異メソッドの定義場所を確認するプログラムを実行する

コマンドライン上で保存したプログラムを実行します。実行結果にtruefalsetruetrueの順で表示されます。

$ ruby special_classes8.rb
true
false
true
true