Clarification needed between class << ClassName and class ClassName

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…

The << indicates you’re adding class level methods rather than instance
level.

Example:

irb(main):001:0> class MyClass
irb(main):002:1> def hello
irb(main):003:2> puts “hello”
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> y = MyClass.new
=> #MyClass:0x2873ac8
irb(main):007:0> y.hello
hello
=> nil

But with the << operator, you can’t call it on an instance.

irb(main):008:0> class << MyClass
irb(main):009:1> def goodbye
irb(main):010:2> puts “bye!”
irb(main):011:2> end
irb(main):012:1> end
=> nil
irb(main):013:0> y = MyClass.new
=> #MyClass:0x2856d60
irb(main):015:0> y.goodbye
NoMethodError: undefined method `goodbye’ for #MyClass:0x2856d60
from (irb):15
from :0
irb(main):016:0> MyClass.goodbye
bye!
=> nil
irb(main):017:0>

–Jeremy

On Nov 30, 2007 3:07 PM, Pixelmech [email protected] wrote:

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…


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

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.

Pixelmech wrote:

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”

Hi –

On Fri, 30 Nov 2007, Pixelmech wrote:

On Nov 30, 2:11 pm, “Jeremy McAnally” [email protected]
wrote:

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.)

See: http://www.wobblini.net/singletons.html for more explanation and
details.

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!

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. :slight_smile:

–Jeremy

On Nov 30, 2007 3:29 PM, David A. Black [email protected] wrote:

opens up a class definition block for the “singleton class” of obj.


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

On Nov 30, 2:11 pm, “Jeremy McAnally” [email protected]
wrote:

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?

See: http://www.wobblini.net/singletons.html for more explanation and
details.

Hmm, David, your Ruby for Rails book appears to be exactly what I’m
looking for to fill in the gaps between the Ruby docs and the Rails
docs. Sold!


def gw
acts_as_n00b
writes_at(www.railsdev.ws)
end

On Fri, 30 Nov 2007 12:07:24 -0800, Pixelmech wrote:

When you see class << obj, believe in your heart, I’m adding directly to
the definition of obj.

I read that as:

when you see foo << bar, believe in your heart, I’m adding directly to
the definition of bar.

But, I could be wrong!

-Thufir

Hi –

On Sat, 1 Dec 2007, Thufir wrote:

the definition of bar.

But, I could be wrong!

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!

Yes, +1 to that. His chapter on this sort of object behavior and
other dynamic stuff is bar none. Excellent.

–Jeremy

On Nov 30, 2007 8:09 PM, Greg W. [email protected] wrote:

acts_as_n00b
writes_at(www.railsdev.ws)
end


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

On Nov 30, 11:58 pm, “David A. Black” [email protected] wrote:

when you see foo << bar, believe in your heart, I’m adding directly to
the definition of bar.

But, I could be wrong!

class is a keyword, so class << obj always means class << obj, no
matter what obj is.
[…]

Ah, I thought it was a general sort of thing, with class as a
placeholder.

-Thufir

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

David A. Black wrote:

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.)

See: http://www.wobblini.net/singletons.html for more explanation and
details.

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.