項目6 Rubyが継承階層をどのように組み立てるかを頭に入れよう
「項目5 実行時の警告に注意しよう」-w
オプションと$VERBOSE
変数の話でした。
知っているべき内容ですが、既に理解している内容だったので1個飛ばし。
内容的には、include時に不可視な特異クラスがスーパークラスとしてクラス階層に挿入されること、
特異メソッドの説明、クラスメソッドが特異クラスのインスタンスメソッドとして格納されること、
メソッドの探索のプロセスについて書かれています。
もちろん、正しいことが書かれていますが、少々わかりにくい。
ここは、メタプログラミングRubyの方が分かりやすいかと思いました。
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/10/10
- メディア: 大型本
- この商品を含むブログ (3件) を見る
ついで
なんとなく分かりにくいので、自分の整理用のためにも、本書の補足としてsample codeと関連および派生したコードと図を一緒に描いて見ました。
この1個右に入っって上をたどるというメソッド探索の流れは図にしないと分かりにくい。
(※図のKernelは省略)
1. インスタンスメソッド
まずは、本書よりも簡単な例。
単なる継承の場合。
class Person def name end end class Customer < Person end customer = Customer.new customer.respond_to?(:name) => true # 両方ともインスタンスメソッドが存在する Customer.instance_methods(:false) Person.instance_methods(:false)
これは良いですよね。
特異メソッド
続いて特異メソッド。
class Person def name end end class Customer < Person end # addressメソッドを追加 customer = Customer.new def customer.address end # ここにはいない Customer.instance_methods(:false) Person.instance_methods(:false) # 特異クラスの確認 >> customer.singleton_class => #<Class:#<Customer:0x00007f8848838650>> # ここにいる customer.singleton_class.instance_methods(:false) # 特異クラスの親クラスはCustomer >> customer.singleton_class.superclass => Customer
3. include(本書の例)
module ThingsWithNames def name end end class Person include ThingsWithNames end class Customer < Person end >> customer = Customer.new >> customer.respond_to?(:name) => true # ここにはいない Customer.instance_methods(:false) Person.instance_methods(:false) # 継承関係を確認。 >> Customer.ancestors => [Customer, Person, ThingsWithNames, Object, Kernel, BasicObject] >> Customer.included_modules => [ThingsWithNames, Kernel] # ThingsWithNamesが差し込まれており、ここにいる >> ThingsWithNames.instance_methods(false) => [:name]
4.extendした場合は?
extendした場合も見て見ましょう。
module ThingsWithNames def name end end class Person extend ThingsWithNames end class Customer < Person end >> Customer.respond_to?(:name) => true # ここにはいない Customer.methods(false) Person.methods(false) # 継承関係 >> Customer.ancestors => [Customer, Person, Object, Kernel, BasicObject] >> Customer.included_modules => [Kernel] # ThingsWithNames が消えました。 # どこにいるかというと、特異クラスの継承ツリーに存在します。 >> Customer.singleton_class.ancestors => [#<Class:Customer>, #<Class:Person>, ThingsWithNames, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject] >> ThingsWithNames.instance_methods(false) => [:name]
- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る