[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