From: Robert Klemme Date: 2013-02-23T20:53:57+09:00 Subject: Re: Class method's has a fuzzy meaning and a sharp meaning On Fri, Feb 22, 2013 at 8:53 PM, Florian Gilcher wrote: > Actually, I groked that concept after I understood that "instance methods" > are actually the special ones. I agree to all else you wrote and your examples but I disagree with the statement above. At least, I view this differently: all methods (even class methods) are instance methods because they are stored in _some_ kind of class. The usual way to define a method is class X def foo end end and module Y def foo end end All instances which inherit X or Y will have the method. Note that this is also true if X is really Class or Module which means that instances of X would be classes or modules. irb(main):002:0> class Class irb(main):003:1> def m; "this is a class method" end irb(main):004:1> end => nil irb(main):005:0> String.m => "this is a class method" irb(main):006:0> Fixnum.m => "this is a class method" Analogous for Module. The distinction David is aiming at is this: method m from the example above is the one that is fuzzily called "class method" because it can be invoked on any class but is not necessarily defined on a class: irb(main):007:0> Class.ancestors => [Class, Module, Object, Kernel, BasicObject] irb(main):008:0> class Module irb(main):009:1> def x; "for classes and modules" end irb(main):010:1> end => nil irb(main):011:0> String.x => "for classes and modules" irb(main):012:0> Enumerable.x => "for classes and modules" The strict ones are really singleton methods defined on a class object: irb(main):013:0> def String.z; "singleton method on a class" end => nil irb(main):014:0> String.z => "singleton method on a class" But singleton methods can be defined on _any_ instance - a class or module is just a special case here: irb(main):015:0> o = Object.new => # irb(main):016:0> def o.s; "singleton method on a non class and non module object" end => nil irb(main):017:0> o.s => "singleton method on a non class and non module object" In all cases - object, class and module - the method definition is stored in a special class which you normally do not get to see: irb(main):018:0> String.singleton_class => # irb(main):019:0> String.singleton_class.instance_method :z => ##z> irb(main):020:0> String.method :z => # irb(main):021:0> o.singleton_class => #> irb(main):022:0> o.singleton_class.instance_method :s => #>#s> irb(main):023:0> o.method :s => #.s> The alternative syntax to define singleton methods reflects that. Instead of def o.s we can do irb(main):024:0> class <> => nil irb(main):025:0> o.t => "another singleton method" Note the "p" is there just to show it's the same class as was returned from o.singleton_method. So even in this case the method definition is stored in a class, albeit a special class which only has one instance: irb(main):026:0> o.singleton_class.new TypeError: can't create instance of singleton class from (irb):26:in `new' from (irb):26 from /usr/bin/irb:12:in `
' There is no way I am aware of to make it have more instances: irb(main):027:0> q = o.dup => # irb(main):028:0> q.singleton_class.equal? o.singleton_class => false irb(main):029:0> q.singleton_class => #> irb(main):030:0> o.singleton_class => #> irb(main):031:0> q = o.clone => # irb(main):032:0> q.singleton_class => #> irb(main):033:0> q.singleton_class.equal? o.singleton_class => false irb(main):034:0> ObjectSpace.each_object(o.singleton_class) {|o| p o} # => 1 But o and q share singleton methods: irb(main):035:0> q.s => "singleton method on a non class and non module object" irb(main):036:0> q.t => "other singleton method" And incidentally they share the same definition of those singleton methods irb(main):037:0> o.method(:s).unbind => #>#s> irb(main):038:0> q.method(:s).unbind => #>#s> irb(main):039:0> o I can override one and the other stays intact irb(main):041:0> def o.s; "overridden" end => nil irb(main):042:0> o.s => "overridden" irb(main):043:0> q.s => "singleton method on a non class and non module object" irb(main):044:0> o.method(:s).unbind => #>#s> irb(main):045:0> q.method(:s).unbind => #>#s> Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/