Scripsit illa aut ille ?Karsten Meier? <discussion / internetlabor.de>:
> I'm working on the ruby section of the pleac project,
> (http://pleac.sourceforge.net) because I think a good way to learn a new
> language is trying to explain it to somebody else.
> There are a few hundred code snippnets from the famous perl cookbook,
> and one of it is perls local function:
> You can give a global variable inside a block a new value. This is 
> slightly different from normal local variable, because it really changes
> the global variable. I think it is sometimes even useful, when you need 
> to change the predefined global variables, but want to automatically 
> restore them after you are done.

Not really.

  rpolzer@katsuragi ~ $ perl -e '
    $a = 17;
    $p = \$a;
    {
      local $a = 42;
      $q = \$a;
    }
    print "$a, $p<$$p>, $q<$$q>\n";
  '
  17, SCALAR(0x812e798)<17>, SCALAR(0x812155c)<42>

It's more than Save&Restore of the variable contents. It saves and
restores the variable pointers in the symbol table. In fact, both
$a were DIFFERENT variables, which justifies the "declaration-style
syntax" of local.

> def local(var)
>    eval("save = #{var.id2name}")
>    result = yield
>    eval("#{var.id2name} = save")
>    result
> end
[...]
> It works quite well, but I like to know if I can get rid of the eval().
> I already have my variable as symbol, so I think it must be possible
> somehow to restore the variable from the symbol, without use of eval.
> Do you have an idea for a more elegant solution?

I cannot solve THAT problem, but there's another thing:

def local(var)
  eval("save = #{var.id2name}")
  begin
    result = yield
  ensure
    eval("#{var.id2name} = save")
  end
end

Otherwise it doesn't work through exceptions.

What do you need it for? If you don't need to use the $something
variables in the usual way, you could use something like this:

class SaveRestoreVariable < Array
  attr_accessor :value
  def initialize(val)
    @value = val
  end
  def localize(&block)
    push(@value)
    begin
      yield
    ensure
      @value = pop()
    end
  end
end

v = SaveRestoreVariable.new(17)
v.localize() do
  v.value = 42
  puts v.value
end
puts v.value