# Extending object instances with \<\<

**URL:** <https://www.ruby-forum.com/t/extending-object-instances-with/86685>\
**Category:** Ruby\
**Created:** [February 24, 2007, 1:53pm UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685 "2007-02-24T13:53:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [February 24, 2007, 1:53pm UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685/1 "2007-02-24T13:53:22Z")

</div>

Hi,

I’m trying to write a class with a method to extend instances of  
itself to contain additional accessors. I thought using `class << self` would be the most elegant way to go about it, but I’m running  
into some problems. To illustrate:

class Test

# takes an array of symbols to add to the instance.

def add syms  
syms.each { |sym|  
@@\_\_tmp = sym  
$\_\_tmp = sym  
class \<\< self  
#attr\_accessor sym # this would be my preferance, but sym  
isn’t in scope here  
#attr\_accessor $\_\_tmp # this works, but uses globals  
attr\_accessor @@\_\_tmp # this is nearly as bad as using globals  
end # \<\<  
} # each  
end # add  
end # Test

t = Test.new  
t.add [:thingie, :thingie2]

t.thingie=“whatever”  
t.thingie2=“bla”  
puts t.thingie  
puts t.thingie2

I don’t like the idea of using globals to transport the symbol  
information and the class members approach is nearly as bad  
(synchronization issues mainly, apart from elegance). But I can’t  
think of another way to transport dynamic data into the `class<<self`  
block.

Alternatives would be to handle this using `method_missing` though  
that wouldn’t just affect a single instance or using `eval` which  
would involve executing strings I’m banging together.

Another thing I tried was:

…  
self.class.attr\_accessor sym  
…

but that doesn’t work because `attr_accessor` is private (contrary to  
what it says in the documentation…)

Any ideas? Am I missing something?  
-tim

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [February 24, 2007, 2:11pm UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685/2 "2007-02-24T14:11:28Z")

</div>

On 24.02.2007 13:52, Tim B. wrote:

> syms.each { |sym|  
> end # Test  
> information and the class members approach is nearly as bad  
> (synchronization issues mainly, apart from elegance). But I can’t  
> think of another way to transport dynamic data into the `class<<self`  
> block.

There is:

irb(main):017:0\> class Bar  
irb(main):018:1\> def add(\*syms)  
irb(main):019:2\> cl = class\<\<self;self;end  
irb(main):020:2\> cl.instance\_eval { attr\_accessor \*syms }  
irb(main):021:2\> end  
irb(main):022:1\> end  
=\> nil  
irb(main):023:0\> f=Bar.new  
=\> #Bar:0x3c1a40  
irb(main):024:0\> f.add :bar  
=\> nil  
irb(main):025:0\> f.bar=10  
=\> 10  
irb(main):026:0\> f.bar  
=\> 10

> but that doesn’t work because `attr_accessor` is private (contrary to  
> what it says in the documentation…)
> 
> Any ideas? Am I missing something?

See above. Apart from that you could simply use OpenStruct or inherit  
OpenStruct which does all this for you already automagically:

irb(main):013:0\> require ‘ostruct’  
=\> true  
irb(main):014:0\> f=OpenStruct.new  
=\> #  
irb(main):015:0\> f.bar=10  
=\> 10  
irb(main):016:0\> f.bar  
=\> 10

Major difference is that you do not explicitly control accessor creation  
but automatically get _all_ - even spelling errors.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [February 26, 2007, 3:10am UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685/3 "2007-02-26T03:10:36Z")

</div>

On Sat, 24 Feb 2007 14:08:19 +0100, Robert K. wrote:

> > syms.each { |sym|  
> > end # Test  
> > =\> 10  
> > irb(main):016:0\> f.bar  
> > =\> 10
> 
> Major difference is that you do not explicitly control accessor creation  
> but automatically get _all_ - even spelling errors.

Test=Struct.new(\*syms)  
or  
Test=Struct.new(:foo,:bar,:baz)

This will guard you against spelling errors.

–Ken

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [February 26, 2007, 11:10am UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685/4 "2007-02-26T11:10:20Z")

</div>

On 26.02.2007 02:38, Ken B. wrote:

> On Sat, 24 Feb 2007 14:08:19 +0100, Robert K. wrote:
> 
> > Major difference is that you do not explicitly control accessor creation  
> > but automatically get _all_ - even spelling errors.
> 
> Test=Struct.new(\*syms)  
> or  
> Test=Struct.new(:foo,:bar,:baz)
> 
> This will guard you against spelling errors.

That’s true. However, I interpreted the OP’s posting that he needs to  
to the extension on a per instance basis. That does not work with the  
approach you presented.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [February 27, 2007, 1:13am UTC](https://www.ruby-forum.com/t/extending-object-instances-with/86685/5 "2007-02-27T01:13:35Z")

</div>

I think you’re correct. The original poster’s problem was to add  
accessors to instances, splats are handy in the general case but  
instance\_eval is what you need here.
