Dynamic class change?


#1

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


#2

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


#3

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


#4

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.