1.21 jigowatts

Great Scott!

Ruby 環境変数を設定してプログラムから値を取得する

概要

APIキーや、なんらかのID/パスワードなんかはバージョン管理の時に困ります。プライベートリポジトリであればいいのですが、ハードコーディングしてるとGitHubに何度か公開しそうに!いちいち書き換えるのも面倒なので環境変数に設定しておいて、プログラムから取得しようそうしよう。

環境

OS X EI Capitan バージョン 10.11.6
CentOS 7(GUI)
rbenv 1.0.0
ruby 2.3.1

環境変数の設定

まずは環境変数の設定ですね。調べた感じ、.bash_profile.bashrcに書いておけば良さそう。それぞれ読み込まれるタイミングが異なり.bash_profileはログイン時に、.bashrcはbash起動時に読み込まれるらしい。ということは、あまり変更されないものは.bash_profileに、よく変更するものは.bashrcに書けばいいのかな。

参考

本当に正しい .bashrc と .bash_profile の使ひ分け - Qiita

というわけで、今回は.bash_profileに環境変数としてGmailのIDとパスワードを設定してみます。

.bash_profile

GMAIL_ID="example@gmail.com"
GMAIL_PASS="yuruipassword"

export GMAIL_ID GMAIL_PASS

ターミナルで以下のコマンドを実行し、設定を反映。

$ source .bash_profile

これでイケると思ってましたが、Macではターミナルの再起動でも読み込まれるけど、CentOSだとターミナルの再起動じゃ読み込まれない。sourceコマンドを実行したターミナルでは有効なんだけど、新規ウィンドウを立ち上げたりすると設定が引き継がれてません。

なんぞこれ?

とおもって調べてみたところ、シェルにも種類があることを知りました。

参考

ログインシェルとインタラクティブシェルと~/.bashrc達の関係 - Qiita

ログイン時とはログインシェルとしてターミナルが起動したときってことで、CnetOSはターミナルの起動時はインタラクティブシェルとして起動してるってことですかね。

以下のコマンドでログインシェルとして起動しているかを確認してみます。

$ shopt
login_shell    	on

Macのターミナルはログインシェルとして起動している(login_shell on)けど、CentOSはログインシェルではないっぽい(login_shell off)。だから.bash_profileが読まれなかったのか。

そんな違いがあったとは。CentOSは再ログインして.bash_profileを読み込ませました。

値の取得

次に、Ruby側で設定した環境変数の値を取得します。これは簡単。

config.rb

ID = ENV['GMAIL_ID']
PASS = ENV['GMAIL_PASS']

設定ファイルを用意しておく

アプリ用の設定値が一つならまだしも、複数の値を.bash_profileに直接書き込むのもアレなんで、設定ファイルを用意して読み込む方法に。

参考

GitHubで認証情報を盗まれないようにするために | SendGridブログ


application.envファイルを作成。内容は.bash_profileに記述したものですね。.gitignoreに追記するのも忘れずに。ついでにapplication.env.templateファイルも用意して、こっちに雛形を書いて公開しておけば、作成が楽になるってスンポーですね。

application.env

GMAIL_ID="example@gmail.com"
GMAIL_PASS="yuruipassword"

export GMAIL_ID GMAIL_PASS


.bash_profileにsourceコマンドで設定ファイルを読み込むように記述して再ログイン。

.bash_profile

source {application path}/application.env

所感

Ruby環境変数を読むだけの記事のつもりでしたが、シェルの理解が浅かったことがわかり、いい勉強になりました!

  • シェルの設定ファイルは読み込むタイミングが異なる
  • シェルには種類がある

Ruby irbに色を付ける

Tips

irb(Interactive Ruby)の出力に色付けして見やすくしてみます。

Wirbleというライブラリをインストールします。

$ gem install wirble

ホームディレクトリに.irbrcを用意しておくとirb起動時に読み込んで設定してくれるようです。最初はないのでファイルを作って、Wirble用の設定を書きましょう。

~/.irbrc

require 'wirble'

Wirble.init
Wirble.colorize

irbを起動してみた結果、色が付きました。見やすい?

f:id:sh_yoshida:20161114063602p:plain

参考

Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)

Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)

C# Excelファイルを取り込んだ時の未入力セルと空白セル

概要

Excelファイルを読み込んだ時に、空欄のセルがNullになる場合と空文字になる場合がありまして、これが原因のバグを埋め込んでしまいました。ちなみに過去にも同じようなことがあったので忘れないためにメモを残しておきます。

未入力セルと空白セル

「A2」「B2」は両方とも空欄のセルです。

f:id:sh_yoshida:20161026115819p:plain

一見同じに見えますが、ISBLANK関数を使ってみます。

=ISBLANK(テストの対象)

結果はヘッダーに記載の通り「A2」はTRUEに、「B2」はFALSEになります。未入力セルは値がない状態ですが、空白セルは「""」の値があります。

f:id:sh_yoshida:20161026115824p:plain

未入力セルはExcelファイルを新規作成したときのセルの状態ですね。
空白セルは、IF関数を使ったり、プログラムよりセルの値を空文字としてExcel出力した時に作られます。

=IF(true,"")

デバッグにて確認

それではこのExcelファイルをC#のプログラムにて取り込んで中身を見てみます。

取り込むためのライブラリはEPPlusを使いました。パッケージマネージャコンソールよりインストールします。

PM> Install-Package EPPlus
デバッグ用コード
using OfficeOpenXml;
using System;
using System.IO;
using System.Linq;

namespace ExcelLoad
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var pck = new ExcelPackage())
            {
                try
                {
                    using (var stream = File.OpenRead(@"c:\file\ExcelFile.xlsx"))
                    {
                        pck.Load(stream);
                    }
                }
                catch (IOException ioEx)
                {
                    Console.WriteLine(ioEx.Message);
                }

                var ws = pck.Workbook.Worksheets.First();
                foreach (var cell in ws.Cells[1, 1, ws.Cells.End.Row, ws.Cells.End.Column])
                {
                    Console.WriteLine(cell.Value);
                }
            }

            Console.ReadKey(true);
        }
    }
}
未入力セル

Textは空文字「""」ですが、Valueは「null」です。

f:id:sh_yoshida:20161026115806p:plain

空白セル

こちらは両方、空文字「""」です。

f:id:sh_yoshida:20161026115814p:plain

まとめ

運用では、予め用意されたフォーマットファイルを編集して取り込むことになってました。
このファイルであれば、空欄のセルは空文字として扱われます。
ところが、ユーザが新規に作成したExcelファイルを取り込むと空欄のセルがNullとして扱われるため、後続の処理でNullガードがなかったために想定外のエラーとなってしまいました(よくあるやつですね)。

Excelファイルを扱うときは二種類の空欄セルに要注意!