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

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

ありがとうございます。

From: Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
Subject: Re: [ruby-list:50908] Re: 一時的にグローバル変数を差し替える
Date: Sat, 03 Oct 2020 17:06:11 +0900 (JST)
> 永井@知能.九工大です.
> 
> 何度もやるわけではなく,行いたいのは1回だけなので,
> わざわざメソッド定義などしたくないということですね?

はい。前提で書きませんでしたが、そういうことです。
「使うときにシンプルに書けるように、そのためのメソッドをよく考えて作る」
というのは十分可能だと持っていたので。

私が最初に書いた物だと明示的に戻すのがいやでした。
提案いただいたように、ensureに書くべきでしたね。
ensureに書くと、ensureと戻しの結びつきがしっくりきます。

> # 実行前の $stdout が STDOUT である保証はないですよね?

まあ、そこは書く人が知っているということで。
(メソッドにするならそうはいかないですが)

一番しっくりくるのは、最初に書いた、
File.open("xxx","w") do |$stdout|
  something
end
ですね。

落としどころとしては、専用メソッドを作るということで、
最初のメールで書いていただいた
def self.temp_sout(path)
が良いような気がしてきました。

> 
> > 大谷です。
> > 
> > 永井さん、ありがとうございます。
> > やはり、コンパクトには書きようが無いと言うことですよね。
> > 
> > そうなると、
> >> File.open("xxx","w") do |$stdout|
> >>   something
> >> end
> > が、見た目通りの動作で通れば良いという気もするのですが、
> > グローバル変数一般に許してしまうのは良くなさそうでもあります。
> > 
> > 専用メソッドを作るなら、
> > File.open("xxx","w").for_stdout do
> >   something
> > end
> > の方が、上記に近い書き方かと思いましたが、こうしてしまうと、
> > openする箇所とcloseする箇所が異なってしまうので、ちょっといやな感じです。
> > 
> > 
> > 
> > From: Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
> > Subject: Re: [ruby-list:50903] 一時的にグローバル変数を差し替える
> > Date: Tue, 29 Sep 2020 23:29:03 +0900 (JST)
> >> 永井@知能.九工大です.
> >> 
> >> たまたま目に入り,そう難しくない話のようなのに
> >> 誰も答えていなかったので取り敢えず.
> >> 
> >> multi-thread のことを考えると,このようなグローバル変数操作は
> >> あまり勧められることではないように思いはしますが,こんな感じでしょうか.
> >> ===========================================================================
> >> #! /usr/bin/ruby
> >> 
> >> class File
> >>   def self.temp_sout(path)
> >>     sout = $stdout
> >>     begin
> >>       fp = open(path, "w")
> >>       $stdout = fp
> >>       yield
> >>     ensure
> >>       $stdout = sout
> >>       fp.close unless fp.closed?
> >>     end
> >>   end
> >> end
> >> 
> >> #------------------------------------------------------------
> >> if __FILE__ == $0
> >> 
> >>   th = Thread.new{
> >>     15.times{|n|
> >>       puts "thread: #{n} #{$stdout}"
> >>       sleep 1
> >>     }
> >>   }
> >>   
> >>   sleep 5
> >>   
> >>   puts "main: prev #{$stdout}"
> >>   
> >>   File.temp_sout("/tmp/temporal_stdout_test.log"){
> >>     5.times{|n|
> >>       puts "temp: #{n} #{$stdout}"
> >>       sleep 1
> >>     }
> >>   }
> >>   
> >>   puts "main: post #{$stdout}"
> >>   
> >>   th.join
> >> 
> >> end
> >> ===========================================================================
> >> 勘違いしていて,望んでいることと違っていたらごめんなさい.
> >> --
> >> 永井 秀利  (nagai@ai.kyutech.ac.jp)
> >> 九州工業大学大学院情報工学研究院知能情報工学研究系知能情報メディア部門助教
> >> 
> >> From: OOTANI TAKASHI <tksotn@mail.117.cx>
> >> Subject: [ruby-list:50903] 一時的にグローバル変数を差し替える
> >> Date: Mon, 28 Sep 2020 22:19:21 +0900
> >> Message-ID: <20200928221918.7D87.E53C48DF@mail.117.cx>
> >> 
> >> > 大谷ともうします。
> >> > 
> >> > 一時的にグローバル変数を差し替える、
> >> > 
> >> > File.open("xxx","w") do |$stdout|
> >> >   something
> >> > end
> >> > 
> >> > 的なこと(ブロックが終わると元に戻る)をしたいと思ったのですが、
> >> > そういうことは出来ないので、
> >> > 
> >> > File.open("xxx","w") do |f|
> >> >   $stdout = f
> >> >   something
> >> > end
> >> > $stdout = STDOUT
> >> > 
> >> > とする事になるかと思います。
> >> > が、ちょっと美しくない気がします。
> >> > 
> >> > 何か他の手段はありますでしょうか?
> >> > 
> >> > -- 
> >> > tksotn
> >> > 
> > 
> > -- 
> > tksotn
> > 

-- 
tksotn

In This Thread