Can I rehash during execution ?

A

Andreas Habel

Hi there,

here`s my question: I`ve coded some classes for my own ircd and it
works pretty fine. Now I`ve included some more functions that react
bot-like and listen to user commands in different channels.

Unfortunately, it`s very nerving to shutdown the ircd, implement tiny
new features, restart and reconnect to the server everytime.
Is there a possibility to reload or rehash loaded classes during
runtime ? If I implement a new method for a class, I simply want to
reload the class definition and execute the new method in every
instance that is still generated without stoping and restarting my
script.

And another question:
I marshal some classes and write them to hd. Now I chance some class
definitions and add some methods. Do the marshaled classes know these
methods after reload or is there a good solution for catching errors
if not ?

greetings from germany
andreas
 
T

ts

A> Is there a possibility to reload or rehash loaded classes during
A> runtime ? If I implement a new method for a class, I simply want to
A> reload the class definition and execute the new method in every
A> instance that is still generated without stoping and restarting my
A> script.

Just try it

svg% cat c.rb
#!/usr/bin/ruby
class C
def c
puts "c"
end
end
svg%

svg% cat b.rb
#!/usr/bin/ruby
require 'c'

c = C.new
c.c
begin
c.d
rescue
p $!
end

File.open("c.rb", "a") do |f|
f.puts "class C; def d() puts 'd'; end; end"
end

load 'c.rb'
c.d
svg%

svg% b.rb
c
#<NoMethodError: undefined method `d' for #<C:0x40099da4>>
d
svg%

svg% cat c.rb
#!/usr/bin/ruby
class C
def c
puts "c"
end
end
class C; def d() puts 'd'; end; end
svg%

A> And another question:
A> I marshal some classes and write them to hd. Now I chance some class
A> definitions and add some methods. Do the marshaled classes know these
A> methods after reload or is there a good solution for catching errors
A> if not ?

same here :


svg% cat c.rb
#!/usr/bin/ruby
class C
def c
puts "c"
end
end
svg%

svg% cat b.rb
#!/usr/bin/ruby
require 'c'

c = C.new
c.c
begin
c.d
rescue
p $!
end

mar = Marshal.dump(C)

class C
def d
puts "d"
end
def c
puts "x"
end
end

c.c
c.d

Marshal.load(mar)

c.c
c.d
C.new.c
C.new.d
svg%

svg% b.rb
c
#<NoMethodError: undefined method `d' for #<C:0x40099958>>
x
d
x
d
x
d
svg%



Guy Decoux
 
F

Florian Frank

Unfortunately, it`s very nerving to shutdown the ircd, implement tiny
new features, restart and reconnect to the server everytime. Is there
a possibility to reload or rehash loaded classes during runtime ? If I
implement a new method for a class, I simply want to reload the class
definition and execute the new method in every instance that is still
generated without stoping and restarting my script.

Try using
load "klass.rb"
instead of requiring those classes.
 
C

Charles Hixson

Brian said:
...

The marshalled form of an object contains only the class name and the
instance variables; it does not include the methods of the class. You can
see this if you use 'inspect' on the output of Marshal.

So if you redefine class Foo, when you load in an old object it will be of
the new Foo class. In any case the object does not contain the methods of
Foo, it contains only a pointer to the class Foo.

This is why you can't marshal an object with singleton methods.

Regards,

Brian.
Hmm. I can certainly see how that would simplify things. But it
definitely implies that marshalled output can't be transferred between
computers. And probably not even between processors on the same
computer (what with on-the-fly class construction and modification).
What would one use for that? You certainly don't want a copy of the
code for every instance, but I don't see the do-able inbetween position.
 
B

Brian Candler

Hmm. I can certainly see how that would simplify things. But it
definitely implies that marshalled output can't be transferred between
computers. And probably not even between processors on the same
computer (what with on-the-fly class construction and modification).
What would one use for that? You certainly don't want a copy of the
code for every instance, but I don't see the do-able inbetween position.

No, it doesn't imply that marshalled output can't be transferred between
computers - that's exactly what DRb does.

Both ends have to have the same class definition, so you just do
require 'foo.rb'
at both sides to get the definition of class Foo. An instance of Foo can
then be marshaled at A and unmarshaled at B.

If you modify class Foo, say by adding a new method, then clearly the new
method will not appear on the other machine unless you make the same change
there.

But that's how it has to be, unless marshaling an *instance* of Foo would
also marshal the *class* Foo, and all its superclasses and mixins for that
matter (including Object). If Ruby supported that, then a single instance
object would be huge. It would also be a huge security risk, as you'd be
passing across code or AST from one machine to another. Plus there are loads
of inconsistent situations I can imagine [*]

But in all practical applications I've used, it doesn't matter: marshaling
an object of class Foo with instance variables @x,@y,@z then unmarshaling it
simply creates a new instance of Foo (whatever Foo is today) with those
instance variables, and that's exactly what is needed.

Regards,

Brian.

[*] Imagine that 'a' is of class Foo, then I marshal it to disk. Then I
modify class Foo, and create another instance of Foo ('b'). Then I reload
'a' from disk. Should class Foo be reset to its original definition? Either
way, either 'a' or 'b' will not be the same as when it was originally
created, because both 'a' and 'b' are of class Foo and therefore have
identical sets of instance methods at any moment in time.

In a dynamic situation where Foo is being changed over time, you have to
accept that object 'a' which was created as an 'old Foo' will by necessity
become a 'new Foo' as Foo is changed.
 
C

Charles Hixson

Brian said:
No, it doesn't imply that marshalled output can't be transferred between
computers - that's exactly what DRb does.

Both ends have to have the same class definition, so you just do
require 'foo.rb'
at both sides to get the definition of class Foo. An instance of Foo can
... as Foo is changed.
But the problem is that this can't handle class definitions where the
sender has modified the class away from the expectations of the
receipient. Since the code doesn't come along, the modifications aren't
known. I'm not sure what a good solution to this problem would be, and
this *will* handle the more common case where both sides have the same
meanings. And it seem quite likely that added variables would be safely
ignored (since method changes don't propagate). But changed methods
wouldn't propagate their changes...and sometimes this is the action that
I would want.

OTOH, I must admit that so far I haven't even used dRuby at all. Or any
other way of distributing execution. But I am thinking that before too
many years have passed I'll be needing to use something rather along
that line.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top