メタプログラミングを読み終えたので、これから知識の抜け漏れを補って行きます。
下記のブログで試している事を確認して行きます。
やったーRuby技術者認定Gold受かったよー\(^o^)/ - 【旧】PerlerのRuby日記->はてなブログに移行しました
Ruby技術者認定試験(Gold)合格経験
試験後に確認している内容が含まれているので、試験に活きる知識が身につくはず。
メソッドの継承
module MyModule def class_method; puts "OK"; end end module MyModule2 def inst_method; puts "instance method OK"; end end class MyClass # クラスメソッド定義(特異クラスにインスタンスメソッドを定義) extend MyModule # インスタンスメソッド定義 include MyModule2 end class MyClass2 < MyClass end MyClass.class_method # => OK MyClass2.class_method # => OK mc2 = MyClass2 mc2.inst_method # => instance method OK
superはincludeされたクラスで呼び出せるか
module M def method; puts "module M"; super; end end class ParentClass def method; puts "class ParentClass"; end end class ChildClass < ParentClass include M def method; puts "class ChildClass"; super; end end ChildClass.new.method # => class ChildClass # => module M # => class ParentClass 呼び出せた!
ParentClass > M > ChildClass という継承関係
includeを行うとinclude呼び出しクラスの一つ上にスーパークラスが作られる
superclassメソッドでは参照できない
privateメソッドの呼び出し
class ParentClass private def m; puts "OK"; end end class ChildClass < ParentClass def m super end def m2 m end end childclass = ChildClass.new childclass.m # => OK childclass.m2 # => OK
インスタンス変数のスコープ
class C @v = 1 def m @v = 2 end class << C @v = 3 # Cクラスのクラスメソッドを定義 def m # Cクラスのクラスインスタンス変数を参照 @v end end end # クラスインスタンス変数 クラスインスタンス変数はクラスメソッドから参照可能 C.m # => 1 # 生成オブジェクトのインスタンス変数 C.new.m # => 2 # Cクラスの特異クラス内のインスタンス変数 class << C @v end # => 3 # Cクラスの生成オブジェクトにおける特異クラス内のインスタンス変数(ややこしいw) c = C.new class << c puts @v end # => nil # 生成オブジェクト内でインスタンス変数未定義のため。当たり前か。
子クラスでinitialize未定義の場合、親クラスのinitializeが呼び出される
class C1 def initialize(value) puts value end end class C2 < C1 end C2.new("OK") # => OK
superとsuper()
class C1 def m(arg = 1) puts arg end end class C2 < C1 def m(arg) # 親クラスのmメソッドを引数指定ありで呼ぶ super(2) # 親クラスのmメソッドを引数指定あり(super(arg)の省略記法)で呼ぶ super # 親クラスのmメソッドを引数指定なしで呼ぶ super() end end C2.new.m 2 # => 2 # => 2 # => 1
インスタンス変数
Cクラスの生成オブジェクトのインスタンス変数とクラスインスタンス変数
class C # クラスインスタンス変数 @v = 1 def m # Cクラスの生成オブジェクトのインスタンス変数。クラスインスタンス変数とは別物 @v end end # 生成オブジェクトのインスタンス変数にアクセス C.new.m # => nil
クラスインスタンス変数へアクセスする
変数が格納されている適切なオブジェクトにアクセスすることで参照可能
class C @v = 1 # selfはCオブジェクト。selfを付けない場合はCクラスの生成オブジェクトを参照 def self.m puts @v end end # => 1
モジュールから引き継ぐもの
module M CONST = 1 @@v = 2 def instance_method puts "Module M instance_method" end def self.class_method puts "Module M class_method" end end class C include M # クラス変数は引き継がれる puts @@v += 1 # 定数も引き継がれる puts CONST end # => 3 # => 1 # モジュール内のインスタンスメソッドも引き継がれる C.new.instance_method # => Module M instance_method # クラスメソッドは引き継がれない C.class_method NoMethodError: undefined method `class_method' for C:Class
superclassとclass
クラスの継承リスト: Class < Module < Object < Kernel < BasicObject
KernelはObjectにインクルードされており、全クラスより参照可能なメソッドを提供
# 各オブジェクトのスーパークラス class C end C.superclass # => Object Class.superclass # => Module Module.superclass # => Object Object.superclass # => BasicObject Basicbject.superclass # => nil # 各オブジェクトのクラス C.class # => Class Object.class # => Class Basicobject.class # => Class Class.class # => Class Module.class # => Class Kernel.class # => Module