2017-01-19 19 views
0

与えられた場合はファイル名にCSV出力を、与えない場合はstdoutに書き込むメソッドを作りたい。標準出力またはファイル名にCSVを書き込む

私はそれがファイルだかstdoutに、私は本当に私がそれだかどうかに持っているに書き込むことができず、何かのように出力ストリームzを処理したい場合に応じて異なるCSVに自分のコールを処理する必要があるように思えディスク上のファイルまたはstdoutストリーム。

これは可能ですか?以下は

私の試みとエラーである:それはIOオブジェクトではありませんので、

require 'csv' 
require 'pathname' 

require 'csv' 
require 'pathname' 

def write_to_csv_or_stdout foo, bar, z=nil 
    z = Pathname.new(z) if z 
    z ||= $stdout 

    res = [[foo, bar, "baz"]] 
    CSV(z) do |csv| 
    res.each do |row| 
     csv << row 
    end 
    end 
end 


write_to_csv_or_stdout "foo", "bar" 
# foo 
# bar 
#=> foo,bar,baz 
# write_to_csv_or_stdout "foo", "bar", "baz" 
# (NoMethodError) 
+0

あなたの目標は何ですか? 'some_method'、' x'、 'y'、' z'のような一般的な名前は使わないでください。特に未使用変数がある。 –

答えて

0

一つの解決策は、パス名のみオブジェクトを使用していないだろう。

ファイルを開くと、stdoutオブジェクトを使用するのと同じ方法で使用できます。

def some_method x, y, z=nil 
    puts x 
    puts y 
    z = Pathname.new(z).open if z # <== here you get an IO Object back 
    z ||= $stdout 

    res = [["foo", "bar", "baz"]] 
    CSV(z) do |csv| 
    res.each do |row| 
     csv << row 
    end 
    end 
end 
+0

'CSV(z)'に新しいファイル 'z'に書き込むことはできますか? 'z'が存在しない場合、' No such file or directory @ rb_sysopen'を取得します。 – mbigras

+0

@mbigras 'z'を' w'または 'w +'属性で開く必要があります。 –

+0

'z'の条件付き代入が分岐の代わりに線形に読み込まれるので、この方法がより良いと思いますか? – mbigras

2

これはstdoutとファイル名で機能します。

$stdout.dupを使用すると、を閉じることなくioを閉じることができます。

def write_csv(io_or_filename, &block) 
    if io_or_filename.is_a?(IO) 
    CSV.new(io_or_filename, &block) 
    else 
    CSV.open(io_or_filename, 'wb', &block) 
    end 
end 

これは、代わりにCSV(...)を使用することができます:私は、ヘルパーメソッドを使用したい

require 'csv' 

def write_csv(rows, filename = nil) 
    io = filename ? File.open(filename, 'w+') : $stdout.dup 
    CSV(io) do |csv| 
    rows.each do |row| 
     csv << row 
    end 
    end 
ensure 
    io.close 
end 

rows = [["foo", "bar", "baz"]] 

write_csv(rows) 
#=> foo,bar,baz 

write_csv(rows, 'test.csv') 
#=> 'test.csv' written 
+0

お返事ありがとうございます!私は[別の答え](http://stackoverflow.com/a/2192010/2909897)をチェックアウトしました。あなたはあなたの '確実に働くための' begin'と 'end'キーワードは必要ありません:) – mbigras

+0

@mbigras:ありがとう。あなたとrubocopは同意します。 –

0

def some_method(x, y, z = $stdout) 
    write_csv(z) do |csv| 
    csv << # ... 
    end 
end 
関連する問題