ruby - How does 'defining a method' work semantically? -
background:
here understand object model (relative question below):
selfreferences receiver in current stack frame.- when in top level ,
def somemethodimplicit receiverself, creating method sits in anonymous class associatedself. anonymous class happens sit underobject(selfinstance ofobjectclass) when callsomemethod, ruby "takes step right", , lands in anonymous class, finding , invoking method. - this similar goes on when define methods inside of class definitions. if, when inside class definition, say:
def self.classmethodcreating method in anonymous class sits underneathclassclass. methods of class, existing "to right" of class being defined not visible instances of new class.
my question:
how "defining method in class" happen in first place? (semantically)
class objects aren't supposed different normal objects, right?
from understand message handling, class objects have table part of state, presumable meaning instance variable, has names of of instance methods. how method works. (if ruby doesn't find , goes 1 , again, presumably directions next link chain part of state of current class object.)
since ruby doesn't care object type, presume doesn't care it's looking in class objects when doing method up. rather, it's following references , looking bits of state names. so, create own "class objects" without using class keyword don't inherit class class?
if question doesn't make sense, apologize. want know what happens when interpreter encounters def keyword.
when write 'def something' in ruby adding method module. module 'class' (a type of module). depends on 'self' @ time:
class foo # right self 'foo' class << self # right self 'class:foo' end def self.bar # right self 'foo' end end def foo.buz # right self 'foo' end obj = foo.new def obj.baz # right self 'foo:0x007fe8a632fa78' (an instance) end a class type of module. subclassing 1 way of creating pointer 1 module another:
class foo end class bar < foo end > bar.ancestors => [bar, foo, object, kernel, basicobject] another way including mixins:
module mixin end class foo include mixin end > foo.ancestors => [foo, mixin, object, kernel, basicobject] method dispatch works on exists in inheritance chain. it's list (not tree) of parent modules , ordered based on when inheritance created:
# bar.rb module mixina def puts "mixina" super end end module mixinb def puts "mixinb" end end class base def puts "base" super end end class sub < base include mixinb include mixina def puts "sub" super end end obj = sub.new obj.something run:
$ ruby bar.rb sub mixina mixinb inspecting chain:
> sub.ancestors => [sub, mixina, mixinb, base, object, kernel, basicobject] when method call happens in walks list looking method in question. if none of modules in chain have method search starts on @ top instead calls method_missing. in either case, first resolution found wins.
yehuda katz wrote article on stuff in 2009:
Comments
Post a Comment