Oliver said:
Why does this not work?
TypeError: Foo is not a class
from (irb):19
You must have miscopied your error message. I obtain
NoMethodError: private method `attr_accessor' called for Class:Class
attr_accessor is a private method of Module, and as such cannot be
called directly with the dot notation. You can call it with send(), or
like this:
class Foo
self.class.instance_eval { attr_accessor :baz }
end
But nevermind, because this is not what you want!
Foo.baz = :qux
p Foo.baz # => :qux
class Bar
end
Bar.baz = 4
p Bar.baz # => 4
You've just added methods #baz and #baz= to every class. This is
because
class Foo
p(self.class == Class) # => true
end
You want the self << class construct that you mentioned, which is the
singleton class,
class Foo
class << self
attr_accessor :baz
end
end
When you said self.class, you were calling Object#class which tells you
the birth canal of an object. But many things can happen after birth,
and kids can end up really different from their parents! This
difference is described in the singleton class. It's unique to the
object. Above, we are adding a method to Foo's singleton class.
BTW there's nothing special about "class << self". You could also say,
class Foo
end
class << Foo
attr_accessor :baz
end
which is the same thing. "class << x" grabs the singleton class of x.
Hope this helps.