プログラマ・アゲイン blog

還暦を過ぎたけどプログラマ復帰を目指してブログ始めました

requireで読み込むRubyライブラリー

メイン・モジュールの最初に記述するrequireメソッドで、実行に必要となるRubyライブラリーを読み込んでいます。

今回は、読み込んでいるライブラリーについて説明したいと思います。

 

読み込んでいるライブラリー

読み込んでいるライブラリーには、Rubyと一緒に導入されたり、RubyGemsで導入したりしたものと、ユーザーが作成したものとがあります。

ここでは、Rubyと一緒に導入されたり、RubyGemsで導入したりしたもののうち、今回使用しているものを記述します。

対象のライブラリーは以下のものですが、各プログラムの中で全てを記述する必要はなく、実際にコーディングしているのは処理の中で使用するもののみです。

require 'logger'
require 'json'
require 'date'
require 'open3'
require 'win32ole'
require 'rubyXL'
require 'rubyXL/convenience_methods/cell'
require 'rubyXL/convenience_methods/color'
require 'rubyXL/convenience_methods/font'
require 'rubyXL/convenience_methods/workbook'
require 'rubyXL/convenience_methods/worksheet'

それぞれの内容について、説明していきます。

 

ライブラリー内容

logger

loggerは、ログを出力するためのライブラリーです。使い方については、以下のページに詳しく書かれています。

docs.ruby-lang.org

json

jsonは、JSON (JavaScript Object Notation)を扱うライブラリです。

今回、JSON形式でデータを記述し、そのデータをhushに取り込んで使用しました。その時に、このjsonライブラリーのモジュールを使用しています。

JSONファイルを読み込んでrubyオブジェクトに展開するコーディングとしては、以下の部分です。

# JSONファイルの読み込みと展開
def read_json(filename)
    File.open(getAbsolutePath(add_path('HostData', filename)), 'r:BOM|UTF-8') do |file|
      JSON.parse(file.read)
    end
end

4行目でファイルを読んで、parseモジュール関数でJSONからRubyオブジェクトに変換しています。内容については、以下のページに書かれています。

docs.ruby-lang.org

JSONに直接の関係はないですが、前述の例で関連してコーディングしているので、ファイルの読み込みについて説明します。

3行目のFileクラスopenメソッドで、ファイルをオープンしています。指定されるファイルをオープンし、File オブジェクトを生成して返します。ここではブロックを指定して呼び出しているので、File オブジェクトを引数としてブロックを実行しています。ブロックの実行が終了すると、ファイルは自動的にクローズされ、ブロックの実行結果を返します。

getAbsolutePath(add_path('Data', filename))が、実際のパス名も含めたファイル名になっています。

add_pathはユーザー関数で、ファイル名にDataというパスを追加して、相対パス名にしています。

getAbsolutePathもユーザー関数で、中でWIN32OLEクラスのGetAbsolutePathNameメソッドを使っています。これでは、add_pathの相対パス名を基に、絶対パス名の文字列を戻しています。

さらにopenメソッドでは、ファイル名とモード・エンコーディング('r:BOM|UTF-8')を指定しています。

モードの「r」は、オープン・モードの指定で、読み込み専用でファイルを開くことを指定しています。

モードの「:BOM|UTF-8」は、読み込まれた文字列のエンコーディングを文字列で指定しています。:BOMは、その入力に含まれるBOMはあらかじめ削られ、BOMがあった場合、入力された文字列にはそのBOMに対応するエンコーディングが設定されることを指定しています。

因みに、BOMというのは、BOM(バイトオーダーマーク)と呼ばれ、UTF-8UTF-16のファイルの先頭に付けられていることがあるコードの事です。なので、念のために指定しています。

ファイルからの文字列の読み込み方法は、以下のページが参考になると思います。

www.buildinsider.net

rubyオブジェクトに展開したものをhashにセットするコーディングについては、別の機会に説明します。

 

date

dateは、その字の通り、日付を扱うためのライブラリーです。

以下のように、今日の日付をExcelのセルに挿入しています。

worksheet.add_cell(0, 2, "#{Date.today}", nil, false)

詳しくは、以下のページに書かれています。

docs.ruby-lang.org

open3

open3は、プログラムを実行し、そのプロセスの標準入力・標準出力・標準エラー出力にパイプをつなぐライブラリーです。

このライブラリーのcapture3というモジュール関数を、以下のように使用しています。

temp_list, e, s = Open3.capture3("dir #{target_dir}\\*.rb /s /b /a-d")

capture3では、実行したコマンドの標準出力と標準エラー、プロセスの終了ステータスを表すオブジェクトを配列で返してくるので、結果をtemp_list、e、s の3つのオブジェクトで受け取っています。

詳しくは、以下のページに書かれています。

docs.ruby-lang.org

"dir #{target_dir}\\*.rb /s /b /a-d"は、実行するコマンドですが、Windowsのdirコマンドでファイル名の一覧を取得しています。dirコマンドのオプションについては、以下を指定しています。

Windowsのファイル情報を取得する方法は、これ以外にも後述のDirクラスを使う方法などありますが、capture3が簡単かなと思って使いました。

win32ole

win32oleは、OLEオートメーションサーバをRubyで操作するためのクラスです、と言っても何のことやらですが。詳しくは、以下のページに書かれています。

docs.ruby-lang.org

引用させていただくと、

Windowsの多くのアプリケーションやライブラリは、COMと呼ばれるAPI群を利用して他のプログラムから操作できます。WIN32OLEがサポートしているのは、 COMのAPIのうち、特にインタープリタ用のインターフェイスであるOLEオートメーション(IDispatchインターフェイス)とそれに付随するリフレクション用のインターフェイスです。
WIN32OLEオブジェクトは、OLEオートメーションサーバが提供するメソッドやプロパティ(Rubyの属性に対応)をスクリプトから呼び出す手段を提供します。呼び出しには、Rubyのオブジェクトと同様にオブジェクトに続けて「.」とメソッド名、必要であれば引数のリストを記述します。

今回は、Office Excelを操作するために使用しています。Excel用のライブラリーとしては後述のrubyXLもあります。

使い方については、かなり量が多いので、別の機会にいたします。

rubyXL

rubyXLは、Excel用のgemライブラリーです。

gemコマンドで導入しておく必要があります。

requireは、rubyXLだけでなく、いくつかのconvenience_methodsも含める必要があります。それは、バージョン3.4.0以降、メモリフットプリントを削減するために、主要なデータ構造がxlsx形式の個々の機能へのアクセスを提供する便利なメソッドから分離されたからです。 これらの機能を使用する場合は、それぞれのファイルを追加で含める必要があります。 

詳しくは、以下に書かれています。残念ながら英語ですが。

www.rubydoc.info

rubyXLの使い方についても、かなり量が多いので、別の機会にいたします。

また、win32oleからのExcelの使い方とrubyXLの使い方とで違いがあり、その違いについても説明できれば良いなと思っております。

簡単に比較すると、win32oleでExcelを操作した場合は細かく指定できる、rubyXLでExcelを操作した場合は簡単にできる、という感じです。

 

ユーザー・ライブラリーの読み込み

ユーザー・ライブラリーの読み込みについては、個別に使用するライブラリーを指定する方法もありますが、以下のようにまとめて全部読み込むパターンも使っています。

Dir[File.expand_path('..', __FILE__) << '/lib/*.rb'].each do |library|
  require library
end

1行目で、読み込むライブラリー名をディレクトリー情報から読み取ってブロックに渡しています。

ついでに、Dirクラス以下の部分についての説明もしておきます。

File.expand_path('相対パス', __FILE__)は、「第2引数で指定したディレクトリ」を相対パスの基準に、相対パス絶対パスに変換した文字列を返します。第2引数の「__FILE__」は、現在のソースファイル名を返す変数なので、そのファイルの相対パスを基準にすることになります。「'..'」で親ディレクトリーを指定しているので、結果として現在のソースファイルがいるディレクトリーが返ってきます。

ただ、それではユーザーが作成した ./libディレクトリーのライブラリーを指すことになりません。そこで、「<< '/lib/*.rb'」という、ヒアドキュメントを応用しています。

ヒアドキュメントとは、Unixのシェルに由来する記法で、「<<」は、後ろに「終了の記号」を追加します。

ここでは、終了の記号として「/lib/*.rb」が追加され、文字リテラルが生成されます。これにより、./lib/*.rb のファイルが対象となります。

そして「Dir」ですが、「」はDirクラスの特異メソッドで、ワイルドカードの展開を行い、パターンにマッチするファイル名を文字列の配列として返します。

それを、eachメソッドでライブラリー名として1つづつ取り出して、ブロックに渡しています。

2行目で、渡されたライブラリー名をrequireで読み込んでいます。

 

次回は、win32oleを使用したExcel操作についてまとめてみたいと思います。