ã¿ãªããããã«ã¡ã¯ã ãã®èšäºã¯ç¡æã®ç¿»èš³ã§ãïŒæåŸã®ãªã³ã¯ïŒã ç§ã¯100ïŒ æ£ãã翻蚳ã®ãµããããŸããã ããããç§ã¯ãèµ·ãã£ãŠããããšã®äžè¬çãªæ¬è³ªãå®å šã«äŒãããããšä¿¡ããŠããŸãã
ãã®èšäºã¯èª°ã«åœ¹ç«ã€ã§ããããïŒ ãããããRubyã®äœæ¥ã®ããã€ãã®ãã€ã³ããç解ãããã ãã®Ruby on Railséçºè ã®åå¿è åãã§ãã
ãã®èšäºã¯èª°ã«ãšã£ãŠã圹ã«ç«ã¡ãŸãããïŒ æãå¯èœæ§ãé«ãã®ã¯ãçŽè¡çš®ã®Rubyããã°ã©ããŒãšçéå ¥ãã®Ruby on Railséçºè ã§ãã ãã§ã«ãããç¥ã£ãŠããå¯èœæ§ãé«ãã§ãã
ãªã翻蚳ããã®ã§ããïŒ ãã®èšäºã¯ç§ã«ãšã£ãŠã¯é¢çœããã§ããã·ã¢èªã話ãïŒããããç¥èã®ä¹ããïŒã³ãã¥ããã£å šäœãšå ±æããããšããæãããããŸããã
PSè±èªãç¥ã£ãŠãããªããæåŸã®ãªã³ã¯ããã©ã£ãŠãã ããã
以äžã¯ç¿»èš³ã®ããã¹ãã§ãã
å æ¥ãRubyã®ãªããžã§ã¯ããšã¡ãœãããã£ã¹ãããã·ã¹ãã ã«ã€ããŠã®ç°¡åã§ãããããã説æã誰ããç¥ã£ãŠãããã©ãããçã«å°ããŸããã ãããŠãäžéšã®äººã ã®çãã¯ãããããããªãã¯ããã«ã€ããŠæžãã¹ãã§ããã§ããã ã ããããã«èšäºããããŸãã ã¡ãœããæ€çŽ¢ãç¶æ¿ãã¹ãŒããŒã¯ã©ã¹ãã¯ã©ã¹ãããã¯ã¹ã€ã³ãã·ã³ã°ã«ãã³ã¡ãœãããªã©ãRubyã®ãªããžã§ã¯ãã·ã¹ãã ãã©ã®ããã«æ©èœãããã説æããŸãã ç§ã®ç解ã¯ãMRIã®ãœãŒã¹ãèªãããšããã§ã¯ãªããJavaScriptã§äžåºŠãã«ããŒã§äžåºŠããã®ã·ã¹ãã ãåå®è£ ããããšããæ¥ãŸããã å°ãããŠãã»ãšãã©æ£ããå®è£ ãèªã¿ããå Žåã¯ãããããå§ããã®ãè¯ãã§ãããã
å®éã«ãœãŒã¹ãèªãã§ããªãã£ãããããã®èšäºã§ã¯ãå®éã«èµ·ãã£ãŠããããšã®èŠ³ç¹ããã§ã¯ãªããè«çã®èŠ³ç¹ããã«ãŒãã«ã§èµ·ãã£ãŠããããšã説æããŸãã ããã¯ãããã€ãã®ããšãç解ã§ããåãªãã¢ãã«ã§ãã
ããçŽããŸãããã ã¢ãžã¥ãŒã«ããã®ã¿ãã«ããã®ãªããžã§ã¯ãã®ã·ã¹ãã ãã»ãŒå®å šã«äœæã§ããŸãã ã¢ãžã¥ãŒã«ã¯ã¡ãœããã®ããã°ãšèããŠãã ããã ããšãã°ãã¢ãžã¥ãŒã«Aã«ã¯ã¡ãœããfooãšbarãå«ãŸããŠããŸãã
+----------+ | module A | +----------+ | def foo | | def bar | +----------+
def foo ... endãã¢ãžã¥ãŒã«rubyå ã§èšè¿°ãããšããã®ã¡ãœãããã¢ãžã¥ãŒã«ã«è¿œå ãããŸããããã ãã§ãã ã¢ãžã¥ãŒã«ã«ã¯è€æ°ã®èŠªãå«ããããšãã§ããŸãã ããªããæžããšãïŒ
module B include A end
AãBã®èŠªãšããŠè¿œå ããã ãã§ããã¡ãœããã¯ã³ããŒãããŸãããBããAãžã®ãã€ã³ã¿ãŒãäœæããã ãã§ãã
+-----------+ | module A | +-----------+ | def foo | | def bar | +-----------+ ^ | +-----+-----+ | module B | +-----------+ | def hello | | def bye | +-----------+
ã¢ãžã¥ãŒã«ã¯è€æ°ã®èŠªãæã€ããšãã§ããããã«ãã£ãŠããªãŒã圢æãããŸãã ããšãã°ããããã®ã¢ãžã¥ãŒã«ïŒ
module A def foo ; end def bar ; end end module B def hello ; end def bye ; end end module C include B def start ; end def stop ; end end module D include A include C end
ãããã¯ãå å«ã®é åºã«åŸã£ãŠããã®ããªãŒã圢æããŸãã
+-----------+ | module B | +-----------+ | def hello | | def bye | +-----------+ ^ +-----------+ +-----+-----+ | module A | | module C | +-----------+ +-----------+ | def foo | | def start | | def bar | | def stop | +-----------+ +-----------+ ^ ^ +-------------------+-------------------+ | +-----+-----+ | module D | +-----------+
ã¡ãœãããå®çŸ©ããå ŽæãRubyãã©ã®ããã«æ€çŽ¢ãããã説æããéèŠãªãã€ã³ãã¯ãã¢ãã«ã®ãè¡çµ±ãïŒã¢ãžã¥ãŒã«ã®ãç¥å ãïŒã§ãã ã¢ãžã¥ãŒã«ã«ãè¡çµ±ããæäŸããããã«äŸé Œãããšãã¢ãžã¥ãŒã«ã®é åã®åœ¢åŒã§æäŸãããŸãã
>> D.ancestors => [D, C, B, A]
éèŠãªããšã¯ããããæšã®åœ¢ã§ã¯ãªããåçŽãªãã§ãŒã³ã®åœ¢ã®è¡çµ±ã§ããããšã§ãã ãã®ãã§ãŒã³ã¯ãã¡ãœãããèŠã€ããããã«ã¢ãžã¥ãŒã«ãå埩ããé åºã決å®ããŸãã ãã®ãªã¹ããäœæããããã«ãDããå§ããŠããæ·±ãæœãããã¹ãŠã®èŠªãå³ããå·Šã«èŠãŠãããŸãã ãããã£ãŠãã€ã³ã¯ã«ãŒãã³ãŒã«ã®é åºã¯éåžžã«éèŠã§ãã ã¢ãžã¥ãŒã«ã®èŠªã¯é çªã«äžŠã¹ãããããã«ããæ€çŽ¢ãããé çªã決ãŸããŸãã
ã¡ãœãããå®çŸ©ãããŠããå ŽæãèŠã€ããããšãã¯ãå®çŸ©ãããŠããæåã®ã¢ãžã¥ãŒã«ãèŠã€ãããŸã§ç¶æ¿ãã§ãŒã³ã調ã¹ãŸãã ã¢ãžã¥ãŒã«ã«ãã®ã¡ãœãããå«ãŸããŠããªãå Žåã¯ãå床æ€çŽ¢ããŸãããä»åã¯method_missingãšããã¡ãœãããæ¢ããŠããŸãã ã¢ãžã¥ãŒã«ã«ã¡ãœãããå«ãŸããŠããªãå ŽåãNoMethodErroräŸå€ãã¹ããŒãããŸãã ã¢ãžã¥ãŒã«ç¶æ¿ãã§ãŒã³ã¯ã2ã€ã®ã¢ãžã¥ãŒã«ã«åãã¡ãœãããå«ãŸããå Žåã®åé¡ã解決ããŸãã ã¢ãžã¥ãŒã«ãç¶æ¿ãã§ãŒã³ã®æåã§ããã¡ãœãããåŒã³åºãããŸãã
ããã¯ã®æ©èœã䜿çšããŠãåŒã³åºãããšãã«èª°ã®ã¡ãœããã䜿çšãããããå€æã§ããŸãã
>> D.instance_method(:foo) => #<UnboundMethod: D(A)#foo> >> D.instance_method(:hello) => #<UnboundMethod: D(B)#hello> >> D.instance_method(:start) => #<UnboundMethod: D(C)#start>
UnboundMethodã¯ããªããžã§ã¯ãã«ãã€ã³ããããåã®ã¢ãã«ã®ã¡ãœããã®åãªãè¡šçŸã§ãã DïŒAïŒ#fooã衚瀺ãããå ŽåãDã¯Aãã#fooã¡ãœãããç¶æ¿ããããšãæå³ããŸããDãå«ããªããžã§ã¯ãã§#fooãåŒã³åºããšãAã§å®çŸ©ãããã¡ãœãããååŸãããŸãã
ãªããžã§ã¯ããšããã°ããªããããŸã§ãããªãã£ãã®ã§ããïŒ ãããé©çšã§ãããªããžã§ã¯ãããªããã°ãã¡ãœããã®ããã°ã¯è¯ããã®ã§ãã ããã§ãããã§ã¯ã©ã¹ãå®è¡ãããŸãã Rubyã§ã¯ãã¯ã©ã¹ã¯ã¢ãžã¥ãŒã«ã®ãµãã¯ã©ã¹ã§ãããå¥åŠã«èãããŸãããã¡ãœãããæ ŒçŽããããŒã¿æ§é ã§ããããšã«æ³šæããŠãã ããã ã¯ã©ã¹ã¯ãã¡ãœãããæ ŒçŽããä»ã®ã¢ãžã¥ãŒã«ãå«ããããšãã§ãããšãã芳ç¹ããã¯ãã»ãšãã©ã¢ãžã¥ãŒã«ã«äŒŒãŠããŸãããããã€ãã®è¿œå æ©èœããããŸãã ãã®1ã€ã¯ããªããžã§ã¯ããäœæããæ©èœã§ãã
class K include D end k = K.new
ãªããžã§ã¯ãã®ã¡ãœãããã©ãããæ¥ãã®ããå€æããæ©äŒãåã³ãããŸãã
>> k.method(:start) => #<Method: K(C)#start>
ããã¯ãk.startãåŒã³åºããšãã¢ãžã¥ãŒã«Cãã#startã¡ãœãããååŸããããšã瀺ããŠããŸããã¢ãžã¥ãŒã«ã®instance_methodãåŒã³åºããšãUnboundMethodãè¿ãããMethodãªããžã§ã¯ãã®å Žåã¯è¿ãããŸãã éãã¯ãã¡ãœããããªããžã§ã¯ãã«é¢é£ä»ããããŠããããšã§ãã ãªããžã§ã¯ãã«å¯ŸããŠ#callãåŒã³åºããšãåäœã¯k.startãšåãã«ãªããŸãã UnboundMethodsã¯ã次ã®ããã«çŽæ¥åŒã³åºãããšã¯ã§ããŸãã ããããåŒã³åºãããšãã§ãããªããžã§ã¯ãã¯ãããŸããã
ãªããžã§ã¯ããå±ããã¯ã©ã¹ããå§ãŸãã¡ãœãããæ¢ããŠããããã«èŠããŸãã次ã«ãã¡ãœãããå®çŸ©ããå ŽæãèŠã€ãããŸã§ãç¶æ¿ãã§ãŒã³å šäœã調ã¹ãŸãã ãŸããããã¯ã»ãšãã©çå®ã§ãããããäžã€ã®ç§trickããããŸãïŒã·ã³ã°ã«ãã³ã¡ãœããã ã¯ã©ã¹ã«è¿œå ããã«ãæ°ããã¡ãœããããªããžã§ã¯ãã«è¿œå ã§ããŸãããã®ãªããžã§ã¯ãã«ã®ã¿è¿œå ã§ããŸãã åç §ïŒ
>> def k.mart ; end >> k.method(:mart) => #<Method: #<K:0x00000001f78248>.mart>
ãŸããã¢ãžã¥ãŒã«ã«è¿œå ããããšãã§ããŸãã ã¢ãžã¥ãŒã«ã¯ãªããžã§ã¯ãã®äžçš®ã§ãã
>> def B.roll ; end >> B.method(:roll) => #<Method: B.roll>
ã¡ãœããåã«ããã·ã¥ïŒïŒïŒã®ä»£ããã«ïŒãïŒãå«ãŸããå Žåãããã¯ã¡ãœãããã¢ãžã¥ãŒã«å ã«ããã®ã§ã¯ãªãããã®ãªããžã§ã¯ãã«å¯ŸããŠã®ã¿ååšããããšãæå³ããŸãã ãã ããRubyã¯ã¢ãžã¥ãŒã«ã䜿çšããŠã¡ãœãããä¿åãããšä»¥åã«è¿°ã¹ãŸããã åçŽãªå€ããªããžã§ã¯ãã«ã¯ããã®ãããªæ©äŒã¯ãããŸããã§ããã ããã§ã¯ãã·ã³ã°ã«ãã³ã¡ãœããã¯ã©ãã«ä¿åãããŸããïŒ
rubyã®åãªããžã§ã¯ãïŒããã³ãã¢ãžã¥ãŒã«ãšã¯ã©ã¹ããªããžã§ã¯ãã§ããããšãå¿ããªãã§ãã ããïŒã«ã¯ãã·ã³ã°ã«ãã³ã¯ã©ã¹ãåºæã¯ã©ã¹ããŸãã¯ä»®æ³ã¯ã©ã¹ãšãåŒã°ãããããããã¡ã¿ã¯ã©ã¹ããããŸãã ãããã®ã¯ã©ã¹ã®ä»äºã¯ããªããžã§ã¯ãã®ã·ã³ã°ã«ãã³ã¡ãœãããä¿åããããšã§ãã æåã¯ãã¡ãœããã¯å«ãŸãããå¯äžã®èŠªãšããŠãªããžã§ã¯ãã¯ã©ã¹ããããŸãã ãªããžã§ã¯ãkã®å Žåãç¶æ¿ãã§ãŒã³ã¯æ¬¡ã®ããã«ãªããŸãã
+-----------+ | module B | +-----------+ ^ +-----------+ +-----+-----+ | module A | | module C | +-----------+ +-----------+ ^ ^ +-------------------+-------------------+ | +-----+-----+ | module D | +-----------+ ^ +-----+-----+ | class K | +-----------+ ^ +-----+-----+ +---+ | metaclass |<~~~~~~~~+ k | +-----------+ +---+
ãªããžã§ã¯ãã®ã¡ã¿ã¯ã©ã¹ã衚瀺ããããRubyã«äŸé Œã§ããŸãã ããã§ãã¡ã¿ã¯ã©ã¹ã¯ãªããžã§ã¯ãkã«ã¢ã¿ãããããå¿åã¯ã©ã¹ã§ãããKã¯ã©ã¹ã«ã¯ååšããªãã€ã³ã¹ã¿ã³ã¹ã¡ãœãã#martãããããšãããããŸãã
>> k.singleton_class => #<Class:#<K:0x00000001f78248>> >> k.singleton_class.instance_method(:mart) => #<UnboundMethod: #<Class:#<K:0x00000001f78248>>#mart> >> K.instance_method(:mart) NameError: undefined method `mart' for class `K'
泚ç®ã«å€ããç¹ã®1ã€ã¯ãã¡ã¿ã¯ã©ã¹ãç¶æ¿ãã§ãŒã³ã«è¡šç€ºãããªãããšã§ãããã¡ãœãããå®çŸ©ãããŠããå Žæã®æ€çŽ¢ãã§ãŒã³ã«é¢äžããŠããããšãç解ããå¿ èŠããããŸãã
ãªããžã§ã¯ãkã®ã¡ãœãããåŒã³åºããšããªããžã§ã¯ãã¯ã¡ã¿ã¯ã©ã¹ã«ãã®ã¡ãœãããå«ãŸããŠãããã©ãããå°ããã¡ã¿ã¯ã©ã¹ã¯ããã«ã¡ãœããã®å Žæã決å®ããããã«ç¶æ¿ãã§ãŒã³ã調ã¹ãŸãã ã·ã³ã°ã«ãã³ã¡ãœããã¯ã¡ã¿ã¯ã©ã¹ã«ããããªããžã§ã¯ãã®ã¯ã©ã¹ãšãã®ãã¹ãŠã®èŠªã§å®çŸ©ãããŠããã¡ãœãããããåªå ãããŸãã
çŸåšããªããžã§ã¯ããäœæããæ©èœã«å ããŠãã¯ã©ã¹ã®2çªç®ã®ç¹å¥ãªããããã£ã«è¿ã¥ããŠããŸãã ã¯ã©ã¹ã«ã¯ããµãã¯ã©ã¹åãšåŒã°ããç¹å¥ãªåœ¢åŒã®ç¶æ¿ããããŸãã åã¯ã©ã¹ã«ã¯ã¹ãŒããŒã¯ã©ã¹ã1ã€ã ããããããã©ã«ãã§ã¯ãªããžã§ã¯ãã§ãã ã¡ãœããåŒã³åºãã®èŠ³ç¹ãããã¹ãŒããŒã¯ã©ã¹ã¯ã¯ã©ã¹ã®æåã®èŠªã¢ãžã¥ãŒã«ãšèããããšãã§ããŸãã
class Foo < Bar class Foo include Extras =~ include Bar end include Extras end
ãããã£ãŠãç¶æ¿ãã§ãŒã³ã¯ã©ã¡ãã®å Žåã[FooãExtrasãBar]ãæäŸãã以åãšåæ§ã«ã¡ãœããæ€çŽ¢ã®é åºã決å®ããŸãã ïŒå®éã«ã¯ããã®[FooãExtrasãBarãObjectãKernelãBasicObject]ã®ããã«èŠããŸãããããã«èŠãŠãããŸãïŒã Rubyã¯ãã¯ã©ã¹ã®ã€ã³ã¯ã«ãŒããèš±å¯ããªãããšã«ããããªã¹ã³ãã®çœ®æã®ååã«éåããããšã«æ³šæããŠãã ããããã®æ¹æ³ã§äœ¿çšã§ããã®ã¯ã¢ãžã¥ãŒã«ã®ã¿ã§ããµãã¿ã€ãã¯äœ¿çšã§ããŸããã äžèšã®ã¹ããããã¯ããµãã¯ã©ã¹åãã¡ãœããã®æ€çŽ¢é åºã«ã©ã®ããã«åœ±é¿ãããã瀺ããŠããŸããBarãã¯ã©ã¹ã®å Žåãå³åŽã®ã³ãŒãã¯æ©èœããŸããã
ãµãã¯ã©ã¹åãå å«ãšåãå Žåããªããããã®æ©èœã®äž¡æ¹ãå¿ èŠãªã®ã§ããïŒ ãŸããããã¯ç§ãã¡ã«å¥ã®æ©äŒãäžããŸãã ã¯ã©ã¹ã¯ã¹ãŒããŒã¯ã©ã¹ããã·ã³ã°ã«ãã³ã¡ãœãããç¶æ¿ããŸãããããã¯ã¢ãžã¥ãŒã«ã§ã¯çºçããŸããã
module Z def self.z ; :z ; end end class Bar def self.bar ; :bar ; end end class Foo < Bar include Z end # Singleton methods from Bar work on Foo ... >> Bar.bar => :bar >> Foo.bar => :bar # ... but singleton methods from Z don't >> Zz => :z >> Foo.z NoMethodError: undefined method `z' for Foo:Class
ãµãã¯ã©ã¹ã¡ã¿ã¯ã©ã¹ã«ã¯èŠªãšããŠã¹ãŒããŒã¯ã©ã¹ã¡ã¿ã¯ã©ã¹ããããšèšãããšã§ãããã芪ã®èŠ³ç¹ããã¢ãã«åã§ããŸãã
+-----+ +--------------+ | Bar +~~~~~~~~>| #<Class:Bar> | +-----+ +--------------+ ^ ^ | | +--+--+ +-------+------+ | Foo +~~~~~~~~>| #<Class:Foo> | +-----+ +--------------+
å®éãFooãèŠããšããã®#barã¡ãœãããã¡ã¿ã¯ã©ã¹Barããæ¥ãŠããããšãããããŸãã
>> Foo.method(:bar) => #<Method: Foo(Bar).bar> >> Foo.singleton_class.instance_method(:bar) => #<UnboundMethod: #<Class:Bar>#bar>
ã«ãŒãã«å ã®ã¡ãœããã®ç¶æ¿ãšæ€çŽ¢é åºããå å«ãšãµãã¯ã©ã¹åãå«ãã¢ãžã¥ãŒã«ã®ããªãŒãšããŠè¡šçŸããç°ãªã芪é¢ä¿ãäœæããæ¹æ³ãèŠãŸããã ãŸãããªããžã§ã¯ãã¡ãœãããšã·ã³ã°ã«ãã³ã¡ãœããã®åäžããã³è€æ°ã®ç¶æ¿ã«ã€ããŠã説æããŸããã ããã§ããã®ã¢ãã«ã®å 端ã«ããããã€ãã®ããšãèŠãŠã¿ãŸãããã
1ã€ç®ã¯ObjectïŒextendã¡ãœããã§ãã object.extendïŒMïŒãåŒã³åºãããšã«ãããã¢ãžã¥ãŒã«Mã®ã¡ãœããããªããžã§ã¯ãã§äœ¿çšã§ããããã«ããŸãã ã¡ãœãããã³ããŒããã®ã§ã¯ãªãããã®ãªããžã§ã¯ãã®ã¡ã¿ã¯ã©ã¹ã®èŠªãšããŠMãè¿œå ããã ãã§ãã ãªããžã§ã¯ãã«Thingã¯ã©ã¹ãããå Žåã次ã®é¢ä¿ãåŸãããŸãã
+-------+ +-----+ | Thing | | M | +-------+ +-----+ ^ ^ +-------+-----+ | +--------+ +---------+-------+ | object +~~~~~~~~>| #<Class:object> | +--------+ +-----------------+
ãããã£ãŠãã¢ãžã¥ãŒã«ã䜿çšãããªããžã§ã¯ãã®æ¡åŒµã¯ããªããžã§ã¯ãã®ã¡ã¿ã¯ã©ã¹ã«ãã®ã¢ãžã¥ãŒã«ãå«ããããšãšåãã§ãã ïŒå®éãããã€ãã®éãããããŸãããããã¯ãã®ãããã¯ã«ã¯é©çšãããŸããïŒã ãã®ããªãŒãèŠããšããªããžã§ã¯ãã®ã¡ãœãããåŒã³åºããšãã¡ãœããã®ãã£ã¹ãããã·ã¹ãã ã¯ThingïŒMã®ã¡ãœããã䜿çšãããŸãïŒãããã¢ãžã¥ãŒã«Mã§å®çŸ©ãããã¡ãœãããåªå ãã次ã«ãã¡ã¿ã¯ã©ã¹ãªããžã§ã¯ãã¯ãMããã³Thingãããåªå ãããŸãã
ãã®ã³ã³ããã¹ãã¯éèŠã§ããäžè¬çãªæå³ã§ã¯ãMã®ã¡ãœãããThingãããåªå ããããšã¯èšããŸãããããªããžã§ã¯ãã¡ãœããã®åŒã³åºãã«ã€ããŠè©±ããšãã ãã§ãã ã¡ãœãããæ±ããããç¶æ¿ã®é£éãéèŠã§ãã ãããŠãããã¯ãã¹ãŒããŒã®ä»äºã調ã¹ããšãã«çŸããŸãã 次ã®ã¢ãžã¥ãŒã«ã»ãããã芧ãã ããã
module X def call ; [:x] ; end end module Y def call ; super + [:y] ; end end class Test include X include Y end
Testã®ç¶æ¿ãã§ãŒã³ã¯æ¬¡ã®ãšããã§ãïŒ[TestãYãX]ããããã£ãŠãTest.new.callãåŒã³åºããšãYãã#callã¡ãœãããåŒã³åºããŸããããããYãsuperãåŒã³åºããšã©ããªããŸããïŒ Yã«ã¯ç¬èªã®ç¶æ¿ãã§ãŒã³ããããŸãããã€ãŸããYããã®ã¡ãœãããåŒã³åºãããšãã§ãã人ã¯ããŸããã
ãããããããŸããã ã¹ãŒããŒã³ãŒã«ã«åºãããããšããéèŠãªããšã¯ããªããžã§ã¯ãç¶æ¿ãã§ãŒã³ãžã®ã¡ãœããåŒã³åºããè¡ã£ãããšã§ããããã ãã§ãã ã¡ãœããã®æ€çŽ¢ã¯ããªããžã§ã¯ãã®ã¡ã¿ã¯ã©ã¹ã®ç¶æ¿ãã§ãŒã³å ã®ç¹å®ã®ã¡ãœããã®ãã¹ãŠã®å®çŸ©ã®æ€çŽ¢ãšããŠæ³åã§ããŸãã
>> t = Test.new >> t.singleton_class.ancestors.map { |m| m.instance_methods(false).include?(:call) ? m.instance_method(:call) : nil }.compact => [#<UnboundMethod: Y#call>, #<UnboundMethod: X#call>]
ã¡ãœããã®å Žæã決å®ããããã«ãç¶æ¿ãã§ãŒã³ã®æåã®ã¡ãœãããåŒã³åºããŸãã ãã®ã¡ãœãããsuperãåŒã³åºããå Žåãæ€çŽ¢ãå®äºãããŸã§æ¬¡ã®ã¡ãœããã«ãžã£ã³ãããŸãã Testã«ã¢ãžã¥ãŒã«Xãå«ãŸããŠããªãå ŽåãYã§å®çŸ©ããããã®ä»¥å€ã®#callå®è£ ã¯ãªããããsuperãåŒã³åºããšãšã©ãŒã«ãªããŸãã
å®éããã®å ŽåãTest.new.callã¯[ïŒx ,: y]ãè¿ããŸãã
ã»ãŒå®äºããŸããããObjectãKernelãBasicObjectãäœã§ãããã説æããããšãçŽæããŸããã BasicObjectã¯ã·ã¹ãã å šäœã®ã«ãŒãã¯ã©ã¹ã§ãã ããã¯ã¹ãŒããŒã¯ã©ã¹ã®ãªãã¯ã©ã¹ã§ãã ãªããžã§ã¯ãã¯BasicObjectãç¶æ¿ãããã¹ãŠã®ãŠãŒã¶ãŒã¯ã©ã¹ã®åºæ¬ã¹ãŒããŒã¯ã©ã¹ã§ãã ãããã®éãã¯ãBasicObjectã«ã¯ã¡ãœãããã»ãšãã©ãªãã®ã«å¯ŸããObjectã«ã¯å€ãã®ã¡ãœããããããšããããšã§ãïŒïŒ==ãïŒ__ send __ãïŒdupãïŒinspectãïŒinstance_evalãïŒis_aïŒãïŒãªã©ã®ã³ã¢ã¡ãœãããã«ããããŸããã¡ãœãããïŒrespond_toïŒãããã³#to_sã å®éããªããžã§ã¯ãèªäœã«ã¯ããããã¹ãŠã®ã¡ãœãããå«ãŸããŠããããã§ã¯ãããŸããããã«ãŒãã«ããååŸããŸãã ã«ãŒãã«ã¯ãRubyã«ãŒãã«ã®ãã¹ãŠã®ãªããžã§ã¯ãã¡ãœããã®ã»ãããæã€åãªãã¢ãžã¥ãŒã«ã§ãã ãããã£ãŠãrubyã«ãŒãã«ã®ãªããžã§ã¯ãã®ã·ã¹ãã ã衚瀺ããããšãããšã次ã®ããã«ãªããŸãã
+---------------+ +------------+ | | | | | +-----------+----------+ +-------------+ +--------+ +--------+--------+ | | | #<Class:BasicObject> |<~~~~+ BasicObject | | Kernel +~~~~>| #<Class:Kernel> | | | +----------------------+ +-------------+ +--------+ +-----------------+ | | ^ ^ ^ | | | +-------+--------+ | | | | | | +--------+--------+ +----+---+ | | | #<Class:Object> |<~~~~~~~~~~~~~~~~+ Object | | | +-----------------+ +--------+ | | ^ ^ | | | | | | +--------+--------+ +----+---+ | | | #<Class:Module> |<~~~~~~~~~~~~~~~~+ Module |<-----------------------------------+ | +-----------------+ +--------+ | ^ ^ | | | | +--------+--------+ +----+---+ | | #<Class:Class> |<~~~~~~~~~~~~~~~~+ Class | | +-----------------+ +--------+ | ^ | | +-----------------------------------------------+
ãã®å³ã¯ãRubyã«ãŒãã«ã®ã¢ãžã¥ãŒã«ãšã¯ã©ã¹ãBasicObjectãKernelãObjectãModuleãClassããããã®ã¡ã¿ã¯ã©ã¹ãããã³ãããããã¹ãŠã©ã®ããã«é¢é£ããŠãããã瀺ããŠããŸãã ã¯ããBasicObject.singleton_class.superclassã¯ã¯ã©ã¹ã§ãã ã«ããŒã¯ããã®æšœåãªã«ã¬ã³ãåŸãããã«ã¡ãã£ãšããããŒãã¥ãŒæã®éæ³ããããŸãïŒç¿»èš³è ã®ã¡ã¢ïŒã ãããã«ãããRubyã§ã®ã¡ãœããã®ãã£ã¹ããããç解ããå Žåã¯ã次ã®ããšãèŠããŠãããŠãã ããã
- ã¢ãžã¥ãŒã«ã¯ã¡ãœããã®ããã°ã§ã
- ã¢ãžã¥ãŒã«ã«ã¯å€ãã®èŠªãå«ããããšãã§ããŸãã
- ã¯ã©ã¹ã¯ããªããžã§ã¯ããäœæã§ããã¢ãžã¥ãŒã«ã§ãã
- åãªããžã§ã¯ãã«ã¯ããªããžã§ã¯ãã®ã¯ã©ã¹ã芪ãšããŠæã€ã¡ã¿ã¯ã©ã¹ããããŸã
- ãµãã¯ã©ã¹åã¯ã2ã€ã®ã¯ã©ã¹ãšãããã®ã¡ã¿ã¯ã©ã¹ã®ãã€ã³ãã£ã³ã°ãæããŸã
- ã¡ãœããã¯ãããªãŒã家系å³ãã«æµžæŒ¬ããæãå³ããå·Šã«èŠãŠæ€çŽ¢ãããŸãã
ããããç§ã¯ãã®ä»äºã®ãã¹ãŠã®åŸ®åŠããç¥ããŸããã 誰ãç¥ããªãã
å ã®èšäºïŒ blog.jcoglan.com/2013/05/08/how-ruby-method-dispatch-works