what does "class << self" do?

P

petermichaux

Hi,

I'm looking at the rails activerecord base.rb file it's main structure
is shown below. Why have a class inside a class like this? What
advantages are there?

Thanks,
Peter

class Base

# methods ...

class << self # Class methods
# methods ...
end

# methods ...

end
 
T

Trans

These are equiv.

class Base
def self.ameth
# ...
end
end


class Base
class << self
def ameth
# ...
end
end
end


class Base; end
class << Base
def ameth
# ...
end
end

class Base; end
def Base.ameth
# ...
end

They are all our ways to get into the
singletonclass/metaclass/ownclass/
eigenclass/whatever-you-want-to-call-it-class. For a class that's quite
useful b/c its were class methods reside, essentially the object that
*is* the class itself rather then its "instance level".

If that seems confusing, don't worry, it is ;-)

T.
 
M

Mauricio Fernández

These are equiv.

class Base
def self.ameth
# ...
end
end


class Base
class << self
def ameth
# ...
end
end
end
[...]

But

class A
B = 1
def self.foo; B end
class << self; def bar; B end end
end
o = []
o << A.foo
o << A.bar
class << A; B = 2 end
o << A.foo
o << A.bar # => [1, 1, 1, 2]
 
S

Stefan Lang

Hi,

I'm looking at the rails activerecord base.rb file it's main
structure is shown below. Why have a class inside a class like
this? What advantages are there?

Thanks,
Peter

class Base

# methods ...

class << self # Class methods
# methods ...
end

# methods ...

end

You can define methods like attr_accessor, has_many etc.
Example:

class Base
class << self
# At this level we are defining methods
# for the Class instance Base. These methods
# are also called class methods (of the Base class).
def flag(attr_name)
class_eval <<-EOD
def #{attr_name}?
@#{attr_name} == true
end
def #{attr_name}
@#{attr_name} = true
end
def disable_#{attr_name}
@#{attr_name} = false
end
EOD
end
end
end

class Foo < Base
flag :quiet
def initialize
@quiet = false
end
end

f = Foo.new
p f.quiet? # => false
f.quiet
p f.quiet? # => true
f.disable_quiet
p f.quiet? # => false
 
D

David A. Black

Hi --

Hi,

I'm looking at the rails activerecord base.rb file it's main structure
is shown below. Why have a class inside a class like this? What
advantages are there?

Thanks,
Peter

class Base

# methods ...

class << self # Class methods
# methods ...
end

# methods ...

end

Every object in Ruby can have methods of its own, in addition to the
methods it gets from being an instance of its class. Those
"singleton" methods (singleton in the sense of belonging to only one
object, not all instances of a class) live in the object's "singleton
class."

The notation:

class << obj
# ...
end

is how you open up a definition block for the singleton class of
obj. Once you're inside that block, it's just like being inside any
other class definition block -- except that you're defining methods
that only obj will be able to call.

Here's an example:

class C # class definition for all instances of C
def speak
puts "Hi"
end
end

c = C.new
class << c # singleton class of this particular instance of C
def speak
puts "Hello"
end
end

another_c = C.new
another_c.speak # Hi
c.speak # Hello

The example you gave was along the lines of:

class C
class << self
def m
(etc.)

In this case (which is a very common one), the object whose singleton
class you're accessing is the Class object C itself. ("self" is equal
to C at the top level of the class definition body.) So you're
creating methods that will only be callable with C as a receiver:

C.m

Those are class methods. Or, to put it another way, class methods are
singleton methods of Class objects.

You can also define a method for a specific object by doing this:

def c.speak

or this, if it's a class:

def C.speak

or (also for a class):

class C
def self.speak

In other words, in most cases you don't have to manually open up the
singleton class. (But see Mauricio's point about the difference in
constant scope, though in most cases that won't be an issue.)

For more on this, see http://www.wobblini.net/~dblack/i0nas.txt


David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top