[ruby-list:50910] Re: 一時的にグローバル変数を差し替える
From:
dogatana <dogatana@...>
Date:
2020-10-04 00:43:56 UTC
List:
ruby-list #50910
こんにちは、市田です。
どこまで汎用的にするかによりますが、メタプログラミング 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