[ruby-list:50912] Re: 一時的にグローバル変数を差し替える

From: OOTANI TAKASHI <tksotn@...117.cx>
Date: 2020-10-07 14:18:55 UTC
List: ruby-list #50912
大谷です。

ありがとうございます。

「任意のグローバル変数で使える汎用的なメソッドを作る」というのは
そもそも考えていませんでしたが、ありがとうございます。

これを見て、今更気づいたのですが、
global_variable_get/set
って、標準のメソッドには無いどころか、実装しようとするとevalが要るとは!


From: dogatana <dogatana@gmail.com>
Subject: [ruby-list:50910] Re: 一時的にグローバル変数を差し替える
Date: Sun, 4 Oct 2020 09:43:56 +0900
> こんにちは、市田です。
> 
> どこまで汎用的にするかによりますが、メタプログラミング Ruby 第2版4.2.1 using キーワード
> にある with と置き換え用クラスを使うと、利用箇所そのものはコンパクトになります。
> 
> module Kernel
>   def with(replacer)
>     yield
>   ensure
>     replacer.restore
>   end
> end
> 
> class Replacer
>   def initialize(sim, new_value)
>     @sim = sim
>     replace(new_value)
>   end
> 
>   def restore
>     global_variable_set(@sim, @old_value)
>   end
> 
>   private
> 
>   def replace(new_value)
>     @old_value = global_variable_get(@sim)
>     global_variable_set(@sim, new_value)
>   end
> 
>   def global_variable_get(sim)
>     eval "#{sim}"
>   end
> 
>   def global_variable_set(sim, value)
>     eval "#{sim} = value"
>   end
> end
> 
> $val = 1
> puts $val
> with Replacer.new(:$val, 3) do
>   puts $val
> end
> puts $val
> 
> File.open('temp.txt', 'w') do |f|
>   $stdout.puts 'before with'
>   with (Replacer.new(:$stdout, f)) do
>     $stdout.puts 'in with'
>   end
>   $stdout.puts 'after with'
> end

-- 
tksotn

In This Thread

Prev Next