I’m in the middle of Why’s Poignent guide, and this one has me
stumped. Let’s say MyClass exists. I want to add to it. So far, all
the examples have done:
class MyClass
def new_method
…
end
end
Now he adds:
class << MyClass
def new_method
…
end
end
He states the difference is the << operator allows you to alter the
definition of an object. Isn’t that what I’m doing in the first
example as well? Won’t my new_method be added to the class regardless?
He also states:
When you see class << obj, believe in your heart, I’m adding directly
to the definition of obj.
I’m failing to see what the practical difference is…
My guess? << Adds to the class whereas the first example would
override new_method if new_method existed…maybe << would do that
too, not sure. Just a guess.
I’m in the middle of Why’s Poignent guide, and this one has me
stumped. Let’s say MyClass exists. I want to add to it. So far, all
the examples have done:
class MyClass
def new_method
…
end
end
Now he adds:
class << MyClass
def new_method
…
end
end
He states the difference is the << operator allows you to alter the
definition of an object. Isn’t that what I’m doing in the first
example as well? Won’t my new_method be added to the class regardless?
He also states:
When you see class << obj, believe in your heart, I’m adding directly
to the definition of obj.
I’m failing to see what the practical difference is…
irb(main):001:0> class MyClass
irb(main):002:1> class << self
irb(main):003:2> def class_level_method; “class_level_method”; end
irb(main):004:2> end
irb(main):005:1> def instance_level_method; “instance_level_method”; end
irb(main):006:1> end
=> nil
irb(main):007:0> MyClass.class_level_method
=> “class_level_method”
irb(main):008:0> MyClass.new.instance_level_method
=> “instance_level_method”
The << indicates you’re adding class level methods rather than instance level.>
But with the << operator, you can’t call it on an instance.
So you’re essentially added a protected method? Would that be correct?
(or is it private?) So the method could only be used by other methods
withing the class?
Doing this:
class << obj
…
end
opens up a class definition block for the “singleton class” of obj.
Inside that singleton class, the methods you define are available only
to obj. They’re not private methods (which would also be available to
other objects of the same class as obj). They’re singleton methods,
which exist only to be called by that one specific object.
When obj is a class, as in class << SomeClass, the singleton methods
pertain to the class object, and are also called “class methods”.
(They are also special-cased in one or two ways; but for the most
part, giving singleton methods to class objects is just one variant of
the general practice of giving singleton methods to objects.)
–
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details and 2008 announcements!
Right. Just to tie it back to _why’s book, this is where the original
explanation’s mention of “changing the object’s definition” comes in.
When you define a class, you’re creating a Class instance, and when
you use <<, you’re changing the definition of that Class instance
(i.e., changing that object’s definition).
It’s confusing, I know, but if you read David’s link and play with it
in irb, it’ll sink in.
The << indicates you’re adding class level methods rather than instance level.>
But with the << operator, you can’t call it on an instance.
So you’re essentially added a protected method? Would that be correct?
(or is it private?) So the method could only be used by other methods
withing the class?
class is a keyword, so class << obj always means class << obj, no
matter what obj is.
David
–
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details and 2008 announcements!
So, the following ought to work? Cuz the modules are loaded but
ArInstance.find does not invoke the logger.
Thx
module ArSugar
def self.included(base)
RAILS_DEFAULT_LOGGER.debug “running included code”
base.class_eval do
base.extend(ClassMethods)
class << self
alias_method(:old_find, :find) unless method_defined?
(:old_find)
end
end
end
module ClassMethods
RAILS_DEFAULT_LOGGER.debug “class methods”
def find(*args)
RAILS_DEFAULT_LOGGER.debug “my finder”
old_find(args)
end
end
end
opens up a class definition block for the “singleton class” of obj.
Inside that singleton class, the methods you define are available only
to obj. They’re not private methods (which would also be available to
other objects of the same class as obj). They’re singleton methods,
which exist only to be called by that one specific object.
When obj is a class, as in class << SomeClass, the singleton methods
pertain to the class object, and are also called “class methods”.
(They are also special-cased in one or two ways; but for the most
part, giving singleton methods to class objects is just one variant of
the general practice of giving singleton methods to objects.)
Thanks David, I think I get it now - it’s only specific to that
instanced object of the class. I will read the link you sent. I’m not
sure why you’d want to do that to one specific object, but I’m sure I’ll
figure that out as time goes on.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.