# Dynamic class change?

**URL:** <https://www.ruby-forum.com/t/dynamic-class-change/63049>\
**Category:** Ruby\
**Created:** [June 11, 2006, 4:42am UTC](https://www.ruby-forum.com/t/dynamic-class-change/63049 "2006-06-11T04:42:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![scorintha](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/278dde/32.png) [@scorintha](https://www.ruby-forum.com/u/scorintha)\
**Post date:** [June 11, 2006, 4:42am UTC](https://www.ruby-forum.com/t/dynamic-class-change/63049/1 "2006-06-11T04:42:14Z")

</div>

I have a stream I’m listening to that lots of similar things speak on,  
each of which also identifies itself with a unique MAC.  
Say, I have 3 objects organized something like this:  
Class Nic  
End

Class Nic2 \< Nic  
Etc.  
End

Class Nic3 \< Nic2  
Etc.  
End

As time passes, when I hear a new MAC start talking, I dynamically  
create a corresponding object. So, if the first thing I hear is  
something a Nic says, a Nic object can spring into existence, ditto for  
Nic2, etc. So far, seems reasonable.

However, the similar things will sometimes appear as a Nic, then say  
something new and exciting that indicates that they are actually Nic2  
objects (or Nic3, for example).

The simple/crude solution is just to have one nic object with a ‘@type’  
class variable that can get changed once new information appears. Also  
the @type variable could be queried to figure out what the object  
is/does.

But this just doesn’t seem like the ruby way. Is there something obvious  
I should be doing that is sensible and cleaner?

The objective is for the calling routine, over time, to know what type  
of objects it is talking to (and to efficiently collect the various  
types to perform operations on).

Thanks,  
Mark

---

<div class="post-metadata">

**Author:** ![scorintha](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/278dde/32.png) [@scorintha](https://www.ruby-forum.com/u/scorintha)\
**Post date:** [June 11, 2006, 6:08am UTC](https://www.ruby-forum.com/t/dynamic-class-change/63049/2 "2006-06-11T06:08:03Z")

</div>

On Sun, 11 Jun 2006, Mark N. wrote:

> Etc.
> 
> Thanks,  
> Mark

google ‘pimpl’ : public interface private implimentation. a simple ruby  
version illustrating what you are talking about might look like this:

```
 harp:~ > cat a.rb
 class Nic
   def initialize
     @impl = NicImpl.new self
   end
   DELEGATE_METHODS = %w(
     a_method
     another_method
   )
   DELEGATE_METHODS.each do |m|
     module_eval " def #{ m }(*a, &b) @impl.#{ m }(*a, &b) end "
   end
   def hear_something_and_become_nic2
     @impl = NicImpl2.new self
   end
   def hear_something_and_become_nic3
     @impl = NicImpl3.new self
   end
 end
 class NicImpl
   def initialize nic
     @nic = nic
   end
   def a_method
     'all nics have this'
   end
 end
 class NicImpl2 < NicImpl
   def another_method
     'this is a nic2'
   end
 end
 class NicImpl3 < NicImpl
   def another_method
     'this is a nic3'
   end
 end

 nic = Nic.new
 p nic.a_method

 nic.hear_something_and_become_nic2
 p nic.another_method

 nic.hear_something_and_become_nic3
 p nic.another_method

 harp:~ > ruby a.rb
 "all nics have this"
 "this is a nic2"
 "this is a nic3"

```

regards.

-a

---

<div class="post-metadata">

**Author:** ![scorintha](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/278dde/32.png) [@scorintha](https://www.ruby-forum.com/u/scorintha)\
**Post date:** [June 11, 2006, 6:07am UTC](https://www.ruby-forum.com/t/dynamic-class-change/63049/3 "2006-06-11T06:07:53Z")

</div>

Mark N. wrote:

> Etc.  
> End
> 
> As time passes, when I hear a new MAC start talking, I dynamically create a corresponding object. So, if the first thing I hear is something a Nic says, a Nic object can spring into existence, ditto for Nic2, etc. So far, seems reasonable.
> 
> However, the similar things will sometimes appear as a Nic, then say something new and exciting that indicates that they are actually Nic2 objects (or Nic3, for example).
> 
> The simple/crude solution is just to have one nic object with a ‘@type’ class variable that can get changed once new information appears. Also the @type variable could be queried to figure out what the object is/does.
> 
> But this just doesn’t seem like the ruby way. Is there something obvious I should be doing that is sensible and cleaner?

You can deal with this by adding a copy constructor, at least to the  
subclasses (but it can be inherited).

class Nic  
def initialize(nic = nil)  
if nic  
self.property = nic.property  
#…  
end  
end  
end

class Nic2 \< Nic  
end

nic = Nic.new  
nic = Nic2.new(nic)

Cheers,  
Dave

---

<div class="post-metadata">

**Author:** ![scorintha](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/278dde/32.png) [@scorintha](https://www.ruby-forum.com/u/scorintha)\
**Post date:** [June 11, 2006, 11:03pm UTC](https://www.ruby-forum.com/t/dynamic-class-change/63049/4 "2006-06-11T23:03:09Z")

</div>

Mark N. wrote:

> As time passes, when I hear a new MAC start talking, I dynamically  
> create a corresponding object. So, if the first thing I hear is  
> something a Nic says, a Nic object can spring into existence, ditto  
> for Nic2, etc. So far, seems reasonable.
> 
> However, the similar things will sometimes appear as a Nic, then say  
> something new and exciting that indicates that they are actually Nic2  
> objects (or Nic3, for example).

It sounds like you could get away with something like htis:

class Nic  
attr\_accessor :mac  
end

module Nic2  
def do\_nic2\_stuff  
puts “nic2 at #{mac}!”  
end  
end

module Nic3  
end

# when you first hear it

nic = Nic.new  
nic.mac = “12:23…”

# later when you have more info

nic.extend Nic2  
nic.do\_nic2\_stuff # ==\> nic2 at 12:23…!

This will work as long as the information you get about these objects is  
_monotone_: you never have to back out of extending a nic instance with  
modules.
