Restoring global variables?

Hi,

do I have any possibiliy to save and restore global
and instance variables? I think of something like:

  user@host$ cat l.rb
  class C ; @@i = 0 ; end
  $g = ""

  cache_globals { load 'm.rb' }
  assert $g == "" and C.instance_eval { @@i.zero? }

  user@host$ cat m.rb
  C.instance_eval { @@i += 99 }
  $g << "foo"
  user@host$

There are several workarounds, for example starting another
process. What is the smartest way to do it?

Thanks in advance.

Bertram

···

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

"Bertram Scharpf" <lists@bertram-scharpf.de> schrieb im Newsbeitrag news:20050130214711.GA30470@homer.bertram-scharpf...

Hi,

do I have any possibiliy to save and restore global
and instance variables? I think of something like:

user@host$ cat l.rb
class C ; @@i = 0 ; end
$g = ""

cache_globals { load 'm.rb' }
assert $g == "" and C.instance_eval { @@i.zero? }

user@host$ cat m.rb
C.instance_eval { @@i += 99 }
$g << "foo"
user@host$

There are several workarounds, for example starting another
process. What is the smartest way to do it?

This is one way that's better than another process.

module Kernel
private
  def cache_globals
    store = {}
    global_variables.each {|v| store[v] = eval(v)}
    begin
      return yield
    ensure
      store.each do |n,v|
        begin
          eval "#{n}=v"
        rescue NameError, SyntaxError, ArgumentError
          # ignore
        end
      end
    end
  end
end

$f = 0
p $f
cg { $f = 100; p $f }
p $f

You can also create something with #trace_var:
http://www.ruby-doc.org/core/classes/Kernel.html#M001741

Kind regards

    robert

Hi,

"Bertram Scharpf" <lists@bertram-scharpf.de> schrieb im Newsbeitrag
news:20050130214711.GA30470@homer.bertram-scharpf...
>do I have any possibiliy to save and restore global
>and instance variables? I think of something like:
>
> user@host$ cat l.rb
> class C ; @@i = 0 ; end
> $g = ""
>
> cache_globals { load 'm.rb' }
> assert $g == "" and C.instance_eval { @@i.zero? }
>
> user@host$ cat m.rb
> C.instance_eval { @@i += 99 }
> $g << "foo"
> user@host$
>
>There are several workarounds, for example starting another
>process. What is the smartest way to do it?

This is one way that's better than another process.

module Kernel
private
def cache_globals
   store = {}
   global_variables.each {|v| store[v] = eval(v)}
   begin
     return yield
   ensure
     store.each do |n,v|
       begin
         eval "#{n}=v"
       rescue NameError, SyntaxError, ArgumentError
         # ignore
       end
     end
   end
end
end

$f = 0
p $f
cg { $f = 100; p $f }
p $f

Another nice workaround. Two caveats:

  * Newly created variables aren't destroyed.
  * side effects:

    irb(main):002:0> eq=eval '$='
    => false
    irb(main):003:0> eval '$= = eq'
    (eval):1: warning: modifying $= is deprecated
    => false

You can also create something with #trace_var:
http://www.ruby-doc.org/core/classes/Kernel.html#M001741

Instantiating about 50 trap routines? No. Besides that, the
above solution could be bypassed using a trace. It's a
security question I asked.

Thanks very much anyway, so far.

Bertram

···

Am Montag, 31. Jan 2005, 08:10:47 +0900 schrieb Robert Klemme:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de