# Class atrr\_accessor

**URL:** <https://www.ruby-forum.com/t/class-atrr-accessor/154669>\
**Category:** Ruby\
**Created:** [December 2, 2008, 8:22pm UTC](https://www.ruby-forum.com/t/class-atrr-accessor/154669 "2008-12-02T20:22:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [December 2, 2008, 8:22pm UTC](https://www.ruby-forum.com/t/class-atrr-accessor/154669/1 "2008-12-02T20:22:21Z")

</div>

Why does this not work?

> > class Foo  
> > self.class.attr\_accessor :baz  
> > end  
> > TypeError: Foo is not a class  
> > from (irb):19

I understand that the class \<\< self idiom can be used to work around  
this problem but I would like to understand why the above triggers such  
an error and what is meant by it.

Thanks.

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [December 2, 2008, 9:10pm UTC](https://www.ruby-forum.com/t/class-atrr-accessor/154669/2 "2008-12-02T21:10:51Z")

</div>

On Dec 2, 2:16 pm, Oliver S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Why does this not work?

An ideology?

> > > class Foo  
> > > self.class.attr\_accessor :baz  
> > > end
> 
> TypeError: Foo is not a class  
> from (irb):19

class Module  
public :attr\_accessor  
end

All fixed.

> I understand that the class \<\< self idiom can be used to work around  
> this problem but I would like to understand why the above triggers such  
> an error and what is meant by it.

Well, I think the idea is that you shouldn’t be changing a class’  
interface from the “outside” ie. so willy-nilly. So you are required  
to go “inside” to get the job done. Sort of a caution barrier. But it  
does suck that this requires a second layer, eg. class \<\< self, to get  
there. I have tried a private #meta method in the past.

class Foo  
meta.attr\_accessor :baz  
end

which works, though I’m not sure the term “meta” feels quite right.  
I’ve avoided ever using it though because I know others would look at  
it and think “what?”.

T.

---

<div class="post-metadata">

**Author:** ![ole](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/fbc32d/32.png) [@ole](https://www.ruby-forum.com/u/ole)\
**Post date:** [December 2, 2008, 9:18pm UTC](https://www.ruby-forum.com/t/class-atrr-accessor/154669/3 "2008-12-02T21:18:30Z")

</div>

Oliver S. wrote:

> Why does this not work?
> 
> > > class Foo  
> > > self.class.attr\_accessor :baz  
> > > end  
> > > 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.
