David A. Black in his book - "The Well-Grounded Rubyist" "So class method has a fuzzy meaning and a sharp meaning. Fuzzily, any method that gets called directly on a Class object is a class method. Sharply, a class method is defined, not just called, directly on a Class object. You’ll hear it used both ways, and as long as you’re aware of the underlying engineering and can make the sharp distinctions when you need to, you’ll be fine." As a beginner couldn't take the concept at all. So anyone out there - could you help me the above with some examples?
on 2013-02-21 21:09
on 2013-02-22 20:16
All I think this is just talking about the contexts of a class method
(hard
to say without knowing what's being talked about currently in the book).
For example he's saying the following are referred to as class methods
class Foo
def self.bar # Sharply, a class method is defined, not just called,
directly on a Class object. self is the class Foo here
puts "bar"
end
end
Foo.bar # Fuzzily, any method that gets called directly on a Class
object
is a class method.
Not sure why he uses these terms, they seem more confusing to me than
they
are worth.
2013/2/21 Xavier R. <lists@ruby-forum.com>
on 2013-02-22 20:53
Hi, Actually, I groked that concept after I understood that "instance methods" are actually the special ones. I'll ignore Modules for this explanation. They make things a tiny bit more complex, but without a lot of conceptual gain. In Ruby, callable methods are bound to objects. Classes are objects, so they have methods. Those methods are defined directly on the object itself. All of the following 3 are equivalent: class Foo def self.bar #self is "Foo" in this context! end def Foo.bar end a = self def a.bar end end Which means that they can be directly called: Foo.bar Takeaway: you can, at any time, define a method on any object in Ruby. Even on classes. Now, the real problem - and thats where the Class/Object distinction comes into play: how do I define methods on Objects that do not exist yet? Thats what instance methods do: you define a method without an explicit object. class Foo def bar end end If we inspect those two methods, they have an interesting difference: [3] pry(main)> Foo.method(:bar) => #<Method: Foo.bar> [4] pry(main)> Foo.instance_method(:bar) => #<UnboundMethod: Foo#bar> The first one is _bound_ to an object (the class Foo) and thus can be called on it. The second on is _unbound_, which also means that it cannot be called, because it is not _bound_ yet, making things like "self" meaningless: [5] pry(main)> Foo.method(:bar).call => nil [6] pry(main)> Foo.instance_method(:bar).call NoMethodError: undefined method `call' for #<UnboundMethod: Foo#bar>... Now, the special ability of classes comes into play: they can be _instantiated_, which means that they can create objects that gain all those instance methods as normal methods: [7] pry(main)> Foo.new.method(:bar) => #<Method: Foo#bar> Note the slightly different notation: thats Foo#bar, the instance methods, not Foo.bar, the class method. So, I usually remember the whole system using 2 simple rules: * You can define and call methods on objects * You can define methods that serve as templates for methods that _future_ objects will gain. Those are instance methods. I hope that helped. Regards, Florian P.S.: You can really define methods on any object at any time: [11] pry(main)> def bla [11] pry(main)* s = "string" [11] pry(main)* def s.really? [11] pry(main)* "yes" [11] pry(main)* end [11] pry(main)* s [11] pry(main)* end => nil [12] pry(main)> bla.really? => "yes"
on 2013-02-22 20:59
@Matt and @Florian - to both you thank you very much. Now understood it in all way. You are very helpful. :)
on 2013-02-23 12:54
On Fri, Feb 22, 2013 at 8:53 PM, Florian Gilcher <flo@andersground.net> 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 => #<Object:0x802a6414> 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 => #<Class:String> irb(main):019:0> String.singleton_class.instance_method :z => #<UnboundMethod: #<Class:String>#z> irb(main):020:0> String.method :z => #<Method: String.z> irb(main):021:0> o.singleton_class => #<Class:#<Object:0x802a6414>> irb(main):022:0> o.singleton_class.instance_method :s => #<UnboundMethod: #<Class:#<Object:0x802a6414>>#s> irb(main):023:0> o.method :s => #<Method: #<Object:0x802a6414>.s> The alternative syntax to define singleton methods reflects that. Instead of def o.s we can do irb(main):024:0> class <<o; p self; def t; "another singleton method" end end #<Class:#<Object:0x802a6414>> => 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 `<main>' There is no way I am aware of to make it have more instances: irb(main):027:0> q = o.dup => #<Object:0x8022ef40> irb(main):028:0> q.singleton_class.equal? o.singleton_class => false irb(main):029:0> q.singleton_class => #<Class:#<Object:0x8022ef40>> irb(main):030:0> o.singleton_class => #<Class:#<Object:0x802a6414>> irb(main):031:0> q = o.clone => #<Object:0x802e9db8> irb(main):032:0> q.singleton_class => #<Class:#<Object:0x802e9db8>> 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} #<Object:0x802a6414> => 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 => #<UnboundMethod: #<Class:#<Object:0x802a6414>>#s> irb(main):038:0> q.method(:s).unbind => #<UnboundMethod: #<Class:#<Object:0x802a6414>>#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 => #<UnboundMethod: #<Class:#<Object:0x802a6414>>#s> irb(main):045:0> q.method(:s).unbind => #<UnboundMethod: #<Class:#<Object:0x802a6414>>#s> Cheers robert
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.