https://github.com/yujideveloper/recite_csv
どういうもの?
RubyでCSVを読むときに各行を普通のオブジェクト(PORO)で扱いたいことないですか?僕はあります。
RubyでCSVを読み込む時は↓のような感じでHashっぽいCSV::RowのインスタンスかArrayで扱うことになりますよね。
CSV.foreach("example.csv", headers: true) do |row| puts row["col1"] end CSV.foreach("example.csv") do |row| puts row[0] end
ReciteCSV使うと↓のような感じで使えるようになります。
class Hoge include ReciteCSV::Reader::Builder.new(col1: "COL1", col2: "COL2") end Hoge.new("./example.csv").each do |row| # 行オブジェクトであるrowはHoge::Rowクラスのインスタンスになります puts row.col1 end
特定のカラムの値を決まったルールで変換して処理するみたいなのもできたり。
カラムの変換ロジックを切り出せるのでテスト書きやすくなったりするかもしれません。
class Hoge include ReciteCSV::Reader::Builder.new(col1: "COL1", col2: "COL2") row_methods do # 行オブジェクトに全く新しいメソッドを追加可能 def col1_ex "#{col1}改" end # 行オブジェクトのカラムにアクセスするメソッドをオーバーライド可能 def col2 "#{super} override" end end end Hoge.new("./example.csv").each do |row| puts row.col1_ex puts row.col2 end
ここまでのサンプルで気付いた方もいるかもしれませんが、これはCSV Readerクラスを作るのをサポートするためのGemです。
今のところWriterをサポートする予定はないです。いい感じのコードが思いついたらやるかもしれません。
こだわり
Module Builderパターンを採用しています。Module Builderパターンについて知らない人はTechRachoさんの以下の記事が参考になるので読んでみると良いと思います。
- RubyのModule Builderパターン #1 モジュールはどのように使われてきたか(翻訳)
- RubyのModule Builderパターン #2 Module Builderパターンとは何か(翻訳)
- RubyのModule Builderパターン #3 Rails ActiveModelでの適用例(翻訳)
Module Builderパターンを使ったおかげでancestorsもきれいになっているはずです。
作成されるReaderクラスやそのRowクラスのancestorsに無名モジュールや無名クラスが現れないように気を配ったりしてます。
無名クラスがあると継承関係を追いにくいとかありますしね。
おわりに
作りましたと言っても2017年末にはもう最初のバージョンをリリースしてました。まだまだ怪しい挙動をするところなどあるかもしれませんが、良ければ使ってみてください。
ちなみにReciteCSVの名前の「Recite」は「朗読する」とかそういう感じのところから来ています。
CSVを朗読するように良い感じに扱いたいみたいな思いでつけました。
バグ修正とか機能追加とかなにかあれば気軽にPRもらえると嬉しいです。
0 件のコメント:
コメントを投稿