株式会社クリアコード > ククログ

ククログ


クリアなコードの作り方: オーバースペックな機能を使わない

本当は「…ない」と否定形ではなく「…する」というような肯定形のタイトルにしたかったのですが、すっきりしたタイトルが浮かびませんでした。肯定形で書くと「身の丈にあった機能を使う」です。

このタイトルは、書いている人にとってオーバースペックかどうかではなく、書いているコードにとってオーバースペックかどうかという意味です。初心者だからメタプログラミングはするな、という話ではありません*1。やり方をいくつも知っていると、より汎用的なやり方を選択したくなるでしょうが、汎用的かどうかという基準だけで考えるのではなく、そのコードにあったやり方かどうかという基準でも考えましょうという話です。

コードを読む側を経験するとわかりますが、コードを書いた人がどうしてこのようなコードを書いたかを知っているか知っていないかでコードの読みやすさが違います。もちろん、どうして書いたかを知っている方が読みやすいです。例えると、どうしてそう書いたかがわかるときは地図を持って進んでいるような感じで、わからないときは地図なしで進んでいるような感じです。

ここでは、「コードを書いた人がどうしてそう書いたか」ということを「書いた人の意図」と呼ぶことにします。

書いた人の意図はいろんな方法で伝えられます。本人から説明してもらうこともありますし、ドキュメントに書かれていることもあります。ソースコード中のコメントに書かれていることもありますし、テストコードで書かれていたり、コードそれ自身で書かれていることもあります。ここでは、コード自身で意図を伝えるケースだけを考えます。

それでは、(書く人ではなくコードにとって)身の丈にあった機能を使ってコードを書くと、コード自身で意図を伝えやすくなるということを例を使いながら説明します。

例1: ある文字列が先頭にあることをチェックする

1つめの例は、「ある文字列が先頭にあることをチェックするコード」です。コードはPacknga*2というRubyのライブラリから持ってきました。

正規表現を使う

まずは、正規表現を使って書いたコードです。

1
2
3
text_files = @spec.files.find_all do |file|
  /\Adoc\/text\// =~ file
end

このコードはファイルの中からテキストファイルだけを抽出するコードです。filesメソッドはファイルのパス(文字列)の配列を返します。このfilesメソッドが返す配列の中から"doc/text/"という文字列で始まっているパスだけを抽出しています。

"doc/text/"という文字列で始まっているかという条件を書くために、上の例では正規表現を使っています。この正規表現は、文字列の先頭という位置を示す\Aという部分と、その後に続くdoc\/text\/という部分からなっています。そのため、この正規表現は「"doc/text/"という文字列が先頭にあるかどうかを判断する」という意味になります。

上の例のように、正規表現を使うと文字列がパターンにマッチするかどうかをチェックできます。正規表現では、今回の例で示したパターン以外もいろいろなパターンを示すことができます。例えば、"doc"という文字列が先頭にあって、末尾に"text/"という文字列がある、といったチェックもできます*3。正規表現は短い文字列で様々なパターンを示せる反面、表現の幅が広いためパッと見ただけではどんな文字列にマッチして、どんな文字列にはマッチしないのかを判断しづらいことがあります。

この例では正規表現のたくさんある機能のうち、「\Aを使った文字列の先頭にあるかチェック」と「doc\/text\/を使った"doc/text/"という文字列かチェック」だけを使っています。この機能だけなら正規表現でなくても実現できます。この例に対しては正規表現はオーバースペックではないでしょうか。

ある文字列が先頭にあることをチェックするメソッドを使う

たまたま、Rubyには「ある文字列が先頭にあることをチェックするメソッド」があります。もともとやりたかったこと(「ある文字列が先頭にあることをチェックする」)に対して過不足ない機能です。

1
2
3
text_files = @spec.files.find_all do |file|
  file.start_with?("doc/text/")
end

正規表現ではできることがたくさんあったため、「この機能は使っている」・「この機能は使っていない」ということを注意深く確認する必要がありましたが、String#start_with?を使う場合はレシーバーの文字列が指定した文字列からはじまっているかしかチェックしないため、書いた人の意図が明確になります*4

この例からわかること

正規表現など汎用的な機能はできることが多いため便利ですが、やれることが多いため書いた人の意図が伝わりにくくなる可能性もあります。一方、start_with?のように小さな機能は、やれることが限定されるため、書いた人の意図が伝わりやすくなります。もし、小さな機能で十分であればそちらを優先して使うと、書いた人の意図が伝わりやすいコードになるでしょう。

例2: コメントアウト

次の例はコメントアウトする例です。

以下のような文字列があったとします。

def comment_out(string)
  # ...
end

この文字列に対して以下のように「すべての先頭行に# を追加」したいということです。

# def comment_out(string)
#   # ...
# end
正規表現を使う

正規表現を使うと以下のように書けます。

1
2
3
4
5
6
7
code = <<-EOC
def comment_out(string)
  # ...
end
EOC

code.gsub(/^/, "# ")

この正規表現は^しかないので何にマッチする正規表現なのかすぐにわかります。そのため、正規表現といういろんなことができる機能を使っていても意図が伝わりにくくなるという可能性は低いです。

すべての行に処理をするメソッドを使う

それでは、正規表現ではなくすべての行に処理をするメソッドを使ってみましょう。「すべての行の先頭に指定した文字列を追加する」メソッドがあるなら、そのメソッドがそのものズバリですが、このメソッドは少し機能が足りません。「すべての行に処理をする」ことができるだけで「行頭に指定した文字列を追加する」ことはできません。

1
2
3
4
5
6
7
8
9
10
11
code = <<-EOC
def comment_out(string)
  # ...
end
EOC

commented_code = ""
code.each_line do |line|
  commented_code << "# #{line}"
end
commented_code

各行の先頭に"# "を追加するコードです。実現したいことを素直に書いているのでわかりにくいということはありませんが、正規表現の実装を見たあとでは冗長な感じがします。そのものズバリではない機能を使う場合は書いた人の意図が少し伝わりにくくなります。

この例からわかること

やれることが多いため書いた人の意図が伝わりにくいことがある正規表現ですが、この例では伝わりやすく書けています。一方、each_lineという小さな機能を使った例の方はパッとみたときの意図が伝わりにくくなっています。

ということで、正規表現だから必ずしも意図が伝わりにくくなるということはありません。

なお、以下のようにメソッドにすれば、どちらの書き方でもより意図が伝わりやすくなります。

1
2
3
4
5
6
7
8
9
10
11
def comment_out(code)
  code.gsub(/^/, "# ")
end

def comment_out(code)
  commented_code = ""
  code.each_line do |line|
    commented_code << "# #{line}"
  end
  commented_code
end

メソッドにするということは、コメントアウトしかしない小さな機能を作ったということです。以下のコードの方が正規表現を使った場合やeach_lineを使った場合よりも書いた人の意図が伝わります。コードを書いた人はコメントアウトしたかったんでしょう。

1
comment_out(code)

まとめ

正規表現のようにできることが多い汎用的な機能は便利ですが、書いた人の意図が伝わりにくくなる可能性があるので注意してください*5。汎用的な機能はそれを使いこなせれば細々とした機能の使い方を覚える必要がなくなるので、書く人の学習コストを抑えられる場合があります*6。汎用的な機能で書いたコードが自分の意図を伝えているかを確認してみてください。もし、やりたいことを実現する小さな機能があった場合は、汎用的な機能ではなく、小さな機能を使ったほうが書いた人の意図が伝わりやすくなります。オーバースペックな機能よりも身の丈にあった機能を使いましょう。

もし、身の丈にあった機能がなかった場合は自分で作ることもできます。書いたコードを読んで、自分の意図が伝わっているか考えてみてはいかがでしょうか。

*1 念のため書いておくと、初心者でもメタプログラミングしていいよ、と言っているわけではなくて、どうしろとかいい悪いとかは何も言っていないということです。

*2 Packngaは多言語に対応したドキュメントを生成するためのユーティリティを集めたライブラリです。

*3 このチェックをするための正規表現は/\Adoc.*text\/\z/となります。

*4 ただし、start_with?がどのようなメソッドかがわからないとパッと見ただけではわかりにくいかもしれません。メソッド名から類推できるような気はしますが。。。

*5 ただし、いつも意図が伝わりにくくなるわけではないので、「正規表現禁止!」となるのは考えものです。

*6 汎用的な機能は覚えることが大変なので、もしかしたら、それほど大差はないかもしれません。

2012-11-01

Fx Meta Installerを使った、カスタマイズ済みのFirefoxのインストーラーの作り方

クリアコードでは、Firefoxサポート事業やThunderbirdサポート事業の一環として、ユーザー企業さまの社内で使うためにFirefoxやThunderbirdを一括導入するお手伝いを承っております。その際、クリアコードでは「Fx Meta Installer」というソフトウェアを利用しています。Fx Meta InstallerはGitHubにて公開していますので、誰でも自由に利用することができます。

この記事では、Fx Meta Installerの概要と、簡単な利用手順を解説します。

2014年10月24日:最新のFx Meta Installerの仕様に合わせて、説明を若干更新しました。

  1. はじめに
    1. Fx Meta Installerとは何か?
    2. Fx Meta Installerの実態
    3. 使用・利用の条件について
  2. 必要なもの
    1. Windowsでのビルド環境の構築
    2. Linuxでのビルド環境の構築(Debian、Ubuntu)
  3. ビルドしてみよう
    1. ビルド用設定ファイルの作成
      1. インストールするアプリケーションの設定
      2. Firefoxのバージョンの指定
      3. Firefoxのインストーラーの取得方法に関する設定
      4. サイレントインストールやウィザードの挙動に関する設定
      5. 既定のブラウザの設定
    2. 同梱するファイルの準備
      1. Firefoxのインストーラー
      2. アドオン
      3. 集中管理用の設定ファイル
    3. ビルドする
      1. ビルドスクリプトの実行
      2. メタインストーラーのテスト実行
      3. 配布用メタインストーラーの作成
  4. おわりに

はじめに

Fx Meta Installerとは何か?

Firefoxのインストーラーにはサイレントインストール*1機能があります。しかしながら、この機能ではFirefoxのインストール先やショートカットの作成の有無などは制御できるものの、Firefoxの細かい設定までは変更することができません。設定や挙動を変えた状態にするためには、Firefoxをインストールした後で変更を行うか、もしくは、ソースコードを変更した上で独自ビルドを作成するかのどちらかの方法を選ぶ必要があります。

Fx Meta Installerは、前者の方法でのカスタマイズを支援するソフトウェアです。Fx Meta Installerの最終生成物はWindows用の実行ファイル(インストーラー)となり、これを実行すると、Firefoxのインストール、設定の変更(同梱の設定ファイルの設置)、および同梱したアドオンのインストールを自動的に完了できます。Firefoxのインストーラーは同梱することもできますし、ネットワーク経由で自動的に取得してくることもできます。「Firefoxのインストーラーをキックするインストーラー」ということで、「Fx Meta Installer」という名前にしました。

Fx Meta Installerの実態

Fx Meta Installerは、2つの実行ファイルを作成します。1つは、実際のインストール処理を行うモジュール「fainstall」。もう1つは、実際に頒布することになる最終生成物の実行ファイル「メタインストーラー」です。メタインストーラーの実態は、fainstallとその他の頒布物を併せて7−Zip形式で圧縮した自己解凍書庫ファイルとなります。

Fx Meta Installerは元々、以下のような意図の元で開発されていました。

  • Firefoxを「Firefox用のアドオン形式で開発されたアプリケーションを実行するための依存ライブラリ」と見なして、アドオンのminVersion/maxVersionの条件を満たすバージョンのFirefoxがまだインストールされていなければ(依存関係が満たされていなければ)Firefoxをインストールする。依存関係が満たされていれば、何もしない。
  • その上で、Firefoxの組み込みのモジュール*2としてアドオンをインストールする。

その後、カスタマイズ内容をアドオンの形式で提供することの利点に着目し、FirefoxやThunderbirdの導入案件において利用しやすいよう機能の拡張を行ってきました。その結果、現在ではFirefoxとアドオンの同時インストールだけでなく、集中管理用の設定ファイルの設置や、Firefoxに任意のオプションを指定した状態で起動するためのショートカットの作成なども行えるようになっています。

使用・利用の条件について

fainstallについては、使用および利用にあたっての条件は特にありません。個人的利用、法人での利用、商用利用など、自由に使っていただいて問題ありません。

それに対して、最終的な頒布物となるメタインストーラーの使用および利用の許諾条件は、そのメタインストーラーによってインストールされるソフトウェア自体の使用および利用の許諾条件に依存しますので、くれぐれもご注意下さい。例えば、以下のような制限があり得ます。

  • 同梱したアドオンやプラグインの利用許諾条件として、非営利での利用が必須条件となっている場合、メタインストーラーを有償で販売することはできません。
  • Firefoxを自動的にインストールするように設定した場合、メタインストーラーを不特定多数に向けて無断で一般公開することはできません。一般公開のためにはMozillaの許諾を得る必要があります。詳しくは法人向けFAQの「製品をカスタマイズして配布しても構わないのですか?」の項を参照して下さい*3

必要なもの

Fx Meta Installerは、FirefoxのWindows版インストーラーと同じく、Nullsoft Scriptable Install System(NSIS)によって開発されています。よって、fainstallおよびメタインストーラーをビルドするためには、NSISスクリプトのビルド環境を用意する必要があります。各プラットフォームでのビルド環境構築の手順は以下の通りです。

Windowsでのビルド環境の構築
  1. NSIS v2.46をダウンロードし、インストールします*4
  2. 以下に挙げる、必要なプラグインをインストールします。DLLファイルはC:\Program Files\NSIS\Plugins以下に、ヘッダーファイル*5はC:\Program Files\NSIS\Include以下にインストールして下さい*6
  3. 「config.bat.sample」をコピーし、「config.bat」という名前にします。必要に応じてNSISのインストール先のパスを修正します。例えば、64bit版のWindows 7でNSISを既定の設定でインストールした場合は、「C:\Program Files (x86)\NSIS」と書き換えます。
Linuxでのビルド環境の構築(Debian、Ubuntu)
  1. 必要なパッケージをインストールします。

    $ sudo apt-get install nsis
  2. 必要なプラグインをインストールします。プラグインの一覧は「Windowsでのビルド環境の構築」と同様です。DLLファイルは/usr/share/nsis/Plugins以下に、ヘッダーファイルは/usr/share/nsis/Include以下にインストールして下さい。

ビルドしてみよう

それでは、以下のような仕様のメタインストーラーを作成するという想定で、ビルド手順を順番に解説していきましょう。

  • 必ずFirefox 33.0をインストールする。インストーラーの実行ファイルは同梱する。
  • ウィザードを使わず、実行したら所定の設定でインストールが自動的に完了するものとする。
  • インストール後、Firefoxを既定のブラウザとする。
  • インストール中、何が起こっているか分かるように、進行状況のプログレスバーは表示する。
  • システムモニターを同梱する。
  • 初期設定として、Firefoxとアドオンの自動更新を無効化する。また、この設定をロックして、ユーザーが自分で有効化できないようにする。
ビルド用設定ファイルの作成

Fx Meta Installerの設定は、ビルド時と、ビルド後の2つのタイミングで行うことができます。基本的にはビルド時の設定だけで問題ありませんが、NSISのビルド環境が整っていない環境でも細かい挙動を調整できるように、一部の設定はビルド後も「fainstall.ini」というファイルを使って変更できるようになっています。また、機能の中にはfainstall.iniに設定を書き加えることでしか利用できないものもあります。

ビルド時の設定は、config.nshで行います。サンプルファイルが「config.nsh.sample」という名前で含まれていますので、最初はこれをコピーして使ってください。

このファイルでは、以下の書式で設定を記述します。

!define 設定名 "設定値"

サンプルファイルの内容のままビルドした場合、できあがるメタインストーラーは以下のような仕様になります。

  • Firefoxをインストールする。
  • Firefoxのバージョンは10から99までの間を想定する。
  • Firefoxのダウングレードは行わない。
  • Firefoxのインストーラーが同梱されていない場合は、インストールを中断する。
  • ウィザードを表示する*7
  • Firefoxのインストーラーのウィザードは表示しない。
  • Firefoxを既定のブラウザとしない(現在の状態を維持する)。

では、それぞれの設定を必要に応じて変更していくことにします。

インストールするアプリケーションの設定

Fx Meta Installerは、FirefoxとThunderbirdのどちらかを選択してインストールできるようになっています。Thunderbird用のメタインストーラーを作成する場合には、以下の箇所を変更します。

!define APP_NAME "Thunderbird" ; "Firefox" から変更する

今回はFirefox用のメタインストーラーを作成しますので、この部分の設定は変更しません。

Firefoxのバージョンの指定

Fx Meta Installerでは、Firefoxのバージョンについて細かい指定ができるようになっています。サンプルの設定は、以下のようになっています。

  • Firefoxが全くインストールされていない場合は、Firefoxを新たにインストールする。
  • 10.0から99.99までの間のいずれかのバージョンのFirefoxがインストールされている場合は、何もしない*8
  • 10.0よりも古いバージョンのFirefoxがインストールされている場合は、上記の範囲のバージョンのFirefoxにアップグレードする。
  • 99.99よりも新しいバージョンのFirefoxがインストールされている場合は、インストール処理全体を中止する。

今回はFirefox 33.0のインストールを行うようにしたいところですが、サンプルのままだと、Firefox 10やFirefox 11のように古いバージョンがインストールされている環境では、Firefoxのインストール処理がスキップされてしまいます*9。そこで、以下の通り変更します。

!define APP_MIN_VERSION "33.0" ; "10.0" から変更する

また、Firefox 34やFirefox 35のように新しいバージョンがインストールされている環境でも、やはりFirefoxのインストール処理はスキップされてしまいます。 企業向けの導入においては、システム管理部門で検証済みのバージョンのみ許可し、検証されていないバージョンは、たとえセキュリティアップデートであっても導入を許可しない、という風にFirefoxのバージョンを厳密に固定する場合があります。 今回は新しいバージョンのFirefoxが導入済みの場合でも必ずFirefox 33.0をインストールするようにしたいので、以下の通り変更します。

!define APP_MAX_VERSION "33.0" ; "99.99" から変更する
!define APP_ALLOW_DOWNGRADE      ; コメントアウトを外す
Firefoxのインストーラーの取得方法に関する設定

Fx Meta Installerは、FirefoxやThunderbirdのインストーラーが同梱されている場合にはそれを使い、同梱されていない場合にはNASに置かれたファイルを利用し、それもなければWebサーバーからインストーラーを自動的にダウンロードしてくる、という風に、Firefoxのインストーラーの取得元を順番にフォールバックしていく機能を含んでいます。これは、以下の箇所のコメントアウトを外して適切な設定を行うことで利用できます。

;!define APP_DOWNLOAD_PATH "\\fileserver\shared\Firefox Setup 15.0.1.exe"
;!define APP_DOWNLOAD_URL  "http://download.mozilla.org/?product=firefox-15.0.1&os=win&lang=ja"
;!define APP_HASH          "8d017402de51a144d0e0fe4d3e2132cb"

サンプルからわかる通り、取得したインストーラーが確かに想定しているファイルと同一かどうかを確かめられるように、MD5チェックサムを指定することもできます*10

なお、いずれの方法でもインストーラーを取得できなかった場合には、メタインストーラーはインストール処理を中止します。

今回はネットワーク経由での取得は行わないため、上記の箇所は変更しません。

サイレントインストールやウィザードの挙動に関する設定

Fx Meta Installerはサンプルの状態では、一般的な「インストールの可否を訊ねる」「EULA(エンドユーザー向けの利用許諾書)への同意を求める」といったウィザードを表示するようになっています。

企業向けの導入においては、ログイン時に特定のファイルを自動的に実行するなどの方法で一括導入を行う場合があり、そのようなケースではウィザードの操作を省略する必要があります。そのようなニーズに対応するため、Fx Meta Installerでは2段階のサイレントインストールが可能となっています。

ウィザードやダイアログの類を一切表示しない完全なサイレントインストールを行うようにしたい場合は、以下のように変更します。

!define PRODUCT_INSTALL_MODE "QUIET" ; "NORMAL" から変更する

ウィザードの操作はさせたくないけれどもインストールの進行状況だけは表示させたいという場合*11は、以下のようにします。

!define PRODUCT_INSTALL_MODE "PASSIVE" ; "NORMAL" から変更する

今回は、ウィザードの操作は省略しつつインストールの進行状況を表示したいので、「PASSIVE」に設定します。

既定のブラウザの設定

Fx Meta Installerでは、インストールしたFirefoxをシステムの既定のブラウザにするかどうか*12も設定できます。今回はFirefoxを既定のブラウザにしたいので、以下の通り変更します。

!define DEFAULT_CLIENT "StartMenuInternet\FIREFOX.EXE" ; コメントアウトを外す。

なお、Thunderbirdをインストールする場合で、Thunderbirdを既定のメールクライアントにしたい場合は、以下のように設定します。

!define DEFAULT_CLIENT "Mail\Mozilla Thunderbird"

以上で、メタインストーラの設定は終了です。これ以外にも色々な設定項目がありますが、今回は解説を省略します*13

同梱するファイルの準備

メタインストーラーの挙動を設定できたら、次は、メタインストーラーに含めるファイルを用意します。

メタインストーラーに含めるファイルは、「resources」という名前のフォルダの中に配置します。resourcesフォルダは初期状態では用意されていないので、新しく作成して下さい。

Firefoxのインストーラー

メタインストーラーにFirefoxのインストーラーを同梱するには、ダウンロードしたインストーラーの実行ファイル(「Firefox Setup 33.0.exe」など)をresourcesフォルダに置きます。

今回はFirefox 33.0を同梱したいので、まずはMozillaの公式サイトからFirefox 33.0のリリース版のWindows用インストーラーをダウンロードします。

使用するインストーラは、すべてのファイルを含んだ完全版のインストーラである必要があります。 インストール中に追加のファイルをダウンロードする種類のインストーラは、メタインストーラーに含めることができませんのでご注意ください。 完全版のインストーラは、以下のようなURLで入手できます。

ダウンロードしたファイルは「Firefox Setup 33.0.exe」という名前になっていますので、そのままresourcesフォルダに置いて下さい。 メタインストーラは、「Firefox Setup *.exe」や「Firefox-setup.exe」のような名前のファイルが存在していれば、それをFirefoxのインストーラとして自動的に検出します。

なお、ウィザードを表示するよう設定してメタインストーラーを作成する場合は、ウィザードの途中でFirefoxのEULA参考訳)に同意する画面が表示されるので、そのためのEULAのテキストファイルもを含めておく必要があります。この場合は、EULAの文章をテキストファイルとして保存し、resourcesフォルダに「Firefox-EULA.txt」という名前で置いて下さい。

Firefoxのインストーラーを同梱しなかった場合、メタインストーラーはビルド時の設定に従ってNASおよびWebサーバーからインストーラーの取得を試みます*14

アドオン

メタインストーラーにアドオンを同梱するには、そのアドオンのXPIパッケージをresourcesフォルダに置きます。 Firefoxにはインストール先の distribution/bundles/ 以下に置かれたアドオンをモジュールとして組み込んだ状態で起動する仕組みがあり、メタインストーラーはこの仕組みを利用して、アドオンをFirefoxにインストールします。

今回はシステムモニターを同梱したいので、XPIパッケージ「system_monitor-0.6.3-fx+tb-win32.xpi」をダウンロードし、resourcesフォルダに置いて下さい。

なお、この方法でFirefoxのモジュールとして組み込まれたアドオンは、完全にFirefoxの一部として扱われるため、アドオンマネージャーには表示されず、セーフモードでも無効化されることはありません。ユーザが任意に設定を変更できるようにするためには、アドオンマネージャー以外の場所から設定画面にアクセスできるようにしておくか、アドオンのインストール先を distribution/bundles/ 以下ではなく extensions/ 以下に変更する必要があります。 アドオンのインストール先を変更する方法については、Fx Meta Installerの構成ファイルの中のdoc/usage.txt.jaを参照して下さい。

また、アドオンは何個でもインストールできます。インストールしたいアドオンが複数ある場合は、すべてのアドオンのXPIファイルをresourcesフォルダに置いて下さい。

集中管理用の設定ファイル

メタインストーラーには、集中管理用の設定ファイルを適切な場所にインストールする機能も含まれています。具体的には、拡張子が「.cfg」であるファイルをresourcesフォルダに置くとFirefoxのインストール先のフォルダに、拡張子が「.js」であるファイルをresourcesフォルダに置くとFirefoxのインストール先の defaults/pref/ 以下にインストールされます。

今回はFirefoxとアドオンの自動更新を無効化し、同時に、その設定をロックしたいので、まずは自動更新を無効化する設定をロックする集中管理用の設定ファイルを作成します。以下の内容のファイルを作成し、resourcesフォルダに「autoconfig.cfg」という名前で保存して下さい。

// 最初の行は無視されるため、必ずコメント行とする。
lockPref("app.update.enabled", false);
lockPref("extensions.update.enabled", false);

次に、集中管理用の設定ファイルを読み込ませるための設定ファイルを作成します。以下の内容のファイルを作成し、resourcesフォルダに「autoconfig.js」という名前で保存して下さい。

pref("general.config.filename", "autoconfig.cfg");
pref("general.config.vendor", "autoconfig");
pref("general.config.obscure_value", 0);
ビルドする

以上で、すべての必要なファイルが準備できました。いよいよビルドしてみましょう。

ビルドスクリプトの実行

設定が完了し、必要なファイルを準備できたら、Windows環境であれば「make.bat」を、Linux環境であれば「make.sh」を実行して下さい。ビルドに成功すると、メッセージの最後に「Success」と出力され、「FxMetaInstaller-source」という名前のフォルダが作成されます。このフォルダには、配布用メタインストーラーの構成ファイル一式と、配布用メタインストーラーの実行ファイルを作成するためのバッチファイルが収められています。

ビルドに失敗した場合、メッセージの最後に「Failed to build fainstall.exe!」と表示されます。ビルド時の設定に間違いがないか、必要なプラグインがすべてインストールされているかなどを再確認して下さい。

メタインストーラーのテスト実行

ビルドに成功した場合であっても、resourcesフォルダの内容などにミスがあった場合、期待通りの実行結果を得られません。そのため、この時点でテスト実行しておくことをお薦めします。

テスト用のWindows環境のローカルディスク上に「FxMetaInstaller-source」フォルダを置き、フォルダ内の実行ファイル「fainstall.exe」を実行して下さい。メタインストーラーを実行した場合と同じ処理が行われ、Firefoxのインストールやアドオンのインストールなどが行われます。インストールされたFirefoxの設定が期待通りになっているか、同梱したアドオンが認識されているかなどを確認して下さい。

配布用メタインストーラーの生成

テスト実行で問題がなければ、配布用のメタインストーラーの実行ファイルを作成します。Windows環境のローカルディスク上に「FxMetaInstaller-source」フォルダを置き、その中にあるバッチファイル「FxMetaInstaller.bat」を実行して下さい。この操作により、配布用のメタインストーラーの実行ファイル「FxMetaInstaller.exe」が作成されます。

なお、「FxMetaInstaller-source」フォルダに出力される設定ファイル「fainstall.ini」を編集したり、resourcesフォルダの内容を変更すると、再ビルドが必要ない範囲でメタインストーラの挙動やインストール対象のファイルを変更することができます*15。設定の変更後は、バッチファイル「FxMetaInstaller.bat」を実行して配布用のメタインストーラーの実行ファイルを再作成して下さい。

おわりに

Fx Meta Installerは、上記の例で行った以外にも様々な設定が可能です。詳しい使い方はdocフォルダの中のドキュメントに解説がありますので、参照してみて下さい。

*1 ウィザードを使わずに、あらかじめ決められた通りの設定でインストールを行うこと

*2 ユーザが自分でインストールするアドオンとは異なり、どのユーザでFirefoxを起動してもそのアドオンが組み込まれた状態で起動することになるアドオン。Nortonツールバーなどがこの形式をとっている

*3 なお、公式のFirefoxのバイナリではなく、Firefoxのロゴなどを含まない独自ビルドのバイナリであれば、この限りではありません。

*4 デバッグ時には、デバッグメッセージの出力に対応したバージョンを使うと、詳細なログを参照することができます。

*5 拡張子が「.nsh」であるファイル

*6 64bit版Windowsでは、NSISはC:\Program Files(x86)\NSIS以下にインストールされます。この場合、プラグインのインストール先もC:\Program Files(x86)\NSIS\PluginsおよびC:\Program Files(x86)\NSIS\Include以下となりますので注意して下さい。

*7 サイレントインストールではない。

*8 そのまま処理を継続する

*9 依存関係が満たされていると判断するため

*10 現状では、SHA1などでのハッシュ値を計算するためのNSIS用プラグインにはバグがあり利用できないため、MD5を使用しています。

*11 ウィザードではないので実行を止めることはできません。

*12 Thunderbirdであれば、既定のメールクライアントにするかどうか

*13 詳しくはFx Meta Installerの構成ファイルの中のdoc/usage.txt.jaを参照して下さい。

*14 取得できなければ、エラーとなりインストール処理を中止します。

*15 fainstall.iniでどのような設定が可能かや、どのようなファイルをインストール対象にできるかについては、doc/usage.txt.jaを参照して下さい。

タグ: Mozilla
2012-11-07

退職金共済制度を活用した退職金制度

はじめに

退職金共済とは、会社が社員のために毎月お金を積み立てて退職金を準備する制度で、単独で退職金制度をもつことが困難な企業が加入する共済です。

クリアコードでは、設立2年目にこの退職金共済制度を利用した退職金制度を設けました。当時はまだ会社が安定しているとはいえない状況で将来に対する不安もありました。もし会社に万が一のことがあっても社員が路頭に迷うことがないよう、多少なりとも退職金を用意することができればという思いから、退職金共済制度の活用を決めました。

クリアコードでは、国が運営する中小企業退職金共済制度(以下、「中退共」という)と東京商工会議所が運営する特定退職金共済(以下、「東商退職金共済」という)の2つに加入しています。退職金共済は社員にとっても会社にとってもメリットの多い制度です。

今回は、中退共を中心にその特徴をみていきながら、退職金共済制度活用のメリットとデメリットを紹介します。

中小企業退職金共済制度の概要

制度の目的と運営体制

中退共は昭和34年に中小企業退職金共済法に基づき設けられた中小企業のための国の退職金制度です。中小企業者の相互共済と国の援助で退職金制度を確立します。これによって中小企業の従業員の福祉の増進と、中小企業の振興に寄与することを目的としています。

中退共は独立行政法人勤労者退職金共済機構・中小企業退職金共済事業本部が運営しています。2012年9月末時点で、企業数で36万社以上、加入者は328万人にのぼります。

加入要件

中小企業であることが条件です。

ソフトウェア関連の業種の場合、常用の社員数100名以下もしくは資本金5000万円以下であることが条件となります。また、原則社員全員が加入しなければなりません。特定の部署のみ加入するといったことはできません。

掛金

掛金は月額5000円から3万円の範囲で16種類用意されており、加入する従業員毎に設定します。また、パートタイマーといった短時間労働者向けには2000円から4000円の掛金も用意されています。

掛金は会社が金融機関に納付します。

退職金の支払い

社員が退職したときや、役員に就任したときに、中退共から直接その者に退職金が支払われます。ただし、掛金の納付月数が11ヶ月以下の社員に対しては支払われません。

中退共利用のメリット

給与の一部を退職金の積立に充てた場合、社会保険料や所得税の負担額が減るので、退職金の受取まで考慮すると、手取り金額が増加します。また、社会保険料の一部は会社が負担しますので、会社にとっても法定福利費の削減につながります。

以下、具体的にどのぐらいの金銭的効果があるか検証します。

毎月の給与

ある社員(27歳、給与27万円)について、中退共に加入し毎月3万円を積み立てた場合と、中退共に加入せず毎月の給与に3万円を加算した場合の給与明細は次のとおりです。

中退共に加入した場合の給与明細・・・[1]

給与    270,000円
-健康保険   11,900円
-厚生年金    23,472円
-雇用保険     1,620円
-源泉所得税   5,870円
差引支給額 227,138円
  • 健康保険料および厚生年金保険料は報酬月額28万円とします。
  • 健康保険料率を42.5/1000、厚生年金保険料率を83.83/1000、雇用保険料率を6/1000とします。
  • 住民税は考慮していません。

中退共に加入しなかった場合の給与明細・・・[2]

給与    300,000円
-健康保険   12,750円
-厚生年金   25,149円
-雇用保険    1,800円
-源泉所得税   6,820円
差引支給額  253,481円

[1]と[2]を比較すると、[2]の方が26,343円手取り金額が多くなっています。また、社会保険料(健康保険、厚生年金、雇用保険)の合計額を比べると[2]の方が2,707円多くなっています。

会社が負担する社会保険料には労災保険料や児童手当拠出金も加わってくるため、[1]の方が、毎月2,707円以上低くなります。

退職金

勤続3年で退職した時の退職金支給額は次のとおりです。

[1]のときは、108万円(3万円 * 36ヶ月)が退職金支給額となります。

退職金に対する所得税を計算するにあたっては、次の計算式による所得控除を行います。

勤続年数20年以下の場合 = 40万円 * 勤続年数(80万円に満たない場合は80万円)

Aさんの場合は、40万円 * 3年 = 120万円が所得控除金額となり、退職金支給額よりも大きくなるため、所得税はO円です。

[2]のときは、もちろん退職金はありません。

合計金額の比較

3年間の給与の手取額と退職金の合計金額は次のとおりです。

[1] 227,138円 * 36 + 1,080,000円 = 9,256,968円
[2] 253,481円 * 36               = 9,125,316円

[1]の方が、131,652円多くなります。

また会社の社会保険料負担額は[1]の方が[2]よりも97,452円以上少なくなります。

このように中退共に加入した場合のほうが、社員は手取り金額が増え、会社は社会保険料負担額が減るという効果が得られます。

ただし、健康保険料は負担額が低くても受けられる効果は変わりませんが、厚生年金保険料は負担額が少なければ、将来受け取る年金の額も少なくなりますので、負担額の多少だけで効果を比較することはできません。労働保険も給与が少なければ、その分失業給付や傷病手当が少なくなります。

制度を活用した場合のその他のメリット
国の助成

中小企業退職金共済制度にかかる新規加入掛金助成及び掛金月額変更掛金助成という制度があり、新規加入した時や掛金を増額した時に掛金の一部について助成が受けられます。

掛金の前納

中退共では最大12ヶ月分の掛金を一括して納付することができます。納付した掛金は支払った期の損金に参入することができるため、利益圧縮の効果があります。

退職金共済加入のデメリット

退職金共済の掛金はふだん従業員には意識されません。また退職金が用意されていることが必ずしも、働くことのモチベーションアップにつながるとは限りません。1年未満で退職した場合は、退職金は出ません。掛金は掛け捨てになります。

まとめ

退職金共済を利用した退職金制度を利用した場合、月々の給与を退職金に回すことによって、社会保険料や所得税の負担を軽減することができ、可処分所得が増加します。会社も社会保険料負担が軽減されます。

近年、若い労働者が年金制度など将来への不安から貯蓄を増やす傾向にあることを考慮すると、退職金制度の活用は労働者のニーズに合致するのではないでしょうか。

タグ: 会社
2012-11-14

CentOS 5でCentOS 6用のzshのSRPMをビルドする方法

快適なコマンドラインライフを送るためにはシェルのことをおろそかにできません。シェルは昔からあるツールですが、今でも改良されています。そのため、数年前にリリースされたシェルよりも最近リリースされたシェルの方が便利です。

さて、CentOS 5は今でもメンテナンスされているOSなので、CentOS 5で作業することがあります。しかし、CentOS 5の標準yumリポジトリにあるzshは4.2.6と古いバージョンです。zshの更新履歴を見ると、4.2.6は2005-12-05にリリースされたバージョンで、実に7年前です。マルチバイト文字のサポートは4.3.xから始まっているので、CentOS 5ではzsh上で日本語を扱うことができません*1

CentOS 6の標準yumリポジトリにあるzshは4.3.10で2009-06-01にリリースされたものです。最新*2ではありませんが、日本語も使えるバージョンです。CentOS 5で作業するときも、少なくともこれくらいの新しいバージョンは使いたいところです。このくらいのバージョンになるとおすすめzsh設定も使えます。

ということで、CentOS 5でCentOS 6用のzshのSRPMをビルドしてCentOS 5でzsh 4.3.10を使うための方法を説明します。

ビルド

SRPMを一般ユーザー権限でビルドするためには~/.rpmmacrosなどを用意しないといけませんが、少し面倒です。これを自動化してくれるツールがあります。それがrpmdev-setuptreeコマンドです。

このコマンドはrpmdevtoolsパッケージの中に含まれているのですが、rpmdevtoolsパッケージはCentOS 5では提供されていません。そのため、EPELにあるパッケージを使います*3

それでは、EPELを使えるようにします。ただし、今回はrpmdevtoolsパッケージだけを使いたいので、EPELはデフォルトでは無効にしておきます。

% wget http://ftp.iij.ad.jp/pub/linux/fedora/epel/5/i386/epel-release-5-4.noarch.rpm
% sudo -H rpm -Uvh epel-release-5-4.noarch.rpm
% sudo -H sed -i'' -e 's/enabled=1/enabled=0/' /etc/yum.repos.d/epel.repo

まず、~/.rpmmacrosなどを用意します。

% sudo -H yum install --enablerepo=epel -y rpmdevtools
% rpmdev-setuptree

CentOS 6用のzshのSRPMをダウンロードします。

% wget http://vault.centos.org/6.3/os/Source/SPackages/zsh-4.3.10-5.el6.src.rpm

ビルドに必要なパッケージをインストールします。yum-utilsパッケージに含まれているyum-builddepコマンドが便利です。

% sudo -H yum install -y yum-utils
% sudo -H yum-builddep zsh-4.3.10-5.el6.src.rpm

SRPMをビルドします。本当はrpmbuild --rebuild zsh-4.3.10-5.el6.src.rpmでビルドしたいところですが、CentOS 5のrpmbuildコマンドではCentOS 6用のSRPMのチェックサムを確認できない*4ので、不本意ながら--nomd5付きでSRPMを展開してからビルドします。

% rpm --nomd5 -i zsh-4.3.10-5.el6.src.rpm
% rpmbuild -bb ~/rpmbuild/SPECS/zsh.spec

これで、~/rpmbuild/RPMS/x86_64/zsh-4.3.10-5.x86_64.rpmにRPMができます。

インストール

ビルドしたPRMをインストールします。

% sudo -H rpm -Uvh ~/rpmbuild/RPMS/x86_64/zsh-4.3.10-5.x86_64.rpm

ログインシェルにする場合はchshで変更します。ログインシェルを変更する場合はうまくシェルが起動しなかった場合のために、別のターミナルを開いたままでログインし直すと安全です。うまくログインし直せなかったら別のターミナルに開いたままのシェルでchshして元のシェルに戻せます。このように別のターミナルを開いたまま動作確認をするのは、PAMやsudoの設定を変更するときと同じですね。

まとめ

CentOS 5でCentOS 6用のRPMをビルドする方法を説明しました。具体例としてzshを用いました。zshを用いたのは、実際にCentOS 5のzshで作業するのがとてもつらくて、ビルドの必要性があったからです。

*1 CentOS 5で提供されているbash 3.2では日本語を使えます。bashの更新履歴を見ると、2.05bから使えるようになったようです。

*2 現在は2012-07-24にリリースされた5.0.0が最新です。

*3 サーバーには必要なもの以外インストールしたくない、という場合は別マシンでビルドしてzshのRPMをコピーしてインストールするとよいでしょう。

*4 「cpio: MD5 sum mismatch」というメッセージがでてエラーになります。

2012-11-21

るびま0040号の「Rubyコードの感想戦」とDevLOVE Conference 2012の「リーダブルコードを読んだ後」のお知らせ

るびま0040号の記事とDevLOVE Conference 2012でのセッションの紹介です。

るびまの記事「Rubyコードの感想戦」の紹介

昨日(2012-11-25)、るびま0040号がリリースされました。今回、久しぶりに記事を寄稿しました*1Ruby コードの感想戦 【第 1 回】 WikiRというタイトルの記事です。あの咳さんのコードにコメントをして、気に入らないところがあったら理由をつけながら直していく(自分好みに変えていく)という内容です。記事中で作ったコードや実際のコミット、記事の原稿などはすべてGitHubにあるので、コードをコピー&ペーストしたりせずに動かしてみたいという人はGitHubにあるリポジトリを見てみるとよいでしょう*2

この記事は「Ruby コードの感想戦」という連載の最初の記事です。この連載の趣旨が記事の最初に書かれているので引用します。

るびまには「よい Ruby コードのお手本を示す」というスタイルの青木峰郎さんの「あなたの Ruby コードを添削します」という名連載がありました。

新しく始まるこの連載もコード添削をテーマにした連載です。青木さんの連載との違いは、「よい Ruby コードのお手本を示す」、「Ruby で書くよいコードのベストプラクティスを提供する」というのではなく、「よいコードにも視点の違いによって多様性があり、それぞれの視点を読んだうえで記事を読む人に自分はどう考えるかを考えてもらう」というスタイルをとる点です。結果として、読んだ人が自分のコードを書くときに、視点がひとつ、ふたつ増えているということを期待しています。

この連載では、「ある人がコードにコメントし、そのコメントに対してまた別の人がコメントする」という記事がセットで進んでいきます。コメントする人は特定の誰かではなく、毎回変わっていきます。先生と生徒の関係ではなく、コメントする人、される人、どちらもコードに一家言持ったプログラマです。きっと、いろいろな視点を見つけられるはずです。

「ベストプラクティスを提供するというのではない」というのがいいですね。「この通りやれば大丈夫だ!」というのをなぞってやっていくことが楽なことはわかりますが、それだけで進んでいくと「ベストプラクティス」から少し外れたことに出会うとうまくいかないという危険があることを忘れてはいけません。「ベストプラクティス」を知識として持っているだけではなく、どうしてこれが「ベストプラクティス」とされているのかという理由まで理解して使えれば、少し外れたことでも「ベストプラクティス」を応用して使いこなせるでしょう。

連載の今後の記事ではどんなスタイルになるかわかりませんが、この記事では「どうして私はそう考えたか」、「咳さんはどのように考えてこのコードを書いただろうか」ということを省略せずにしっかり書いています。テクニックよりも、プログラマーがどうしてそのテクニックを使うのかという理由の方を大事にしているということです。信頼できるコードを書くプログラマーなら、どうしてこういうコードにするかということを考えてコードを書いているものです。この記事を読んだプログラマーが信頼できるコードを書くプログラマーになってくれるといいなぁという期待を込めています。

この記事はコードへコメントする記事なので、コードへたくさんコメントしています。最近では、コードへコメントするというと、GitHub上でpull requestしてコメント欄や行コメントでやりとりするというのが「ベストプラクティス」だというのをちらほらと見かけます。しかし、この記事では違う方法を使っています。それは日本語のコメントではなく直接コミットしてコードで伝える方法です。どうしてこの方法を使っているかという理由を引用します。

直接コミットすると、そのコミットには以下の情報が含まれます。

  • どう直したかのサマリー(Use Monitor instead of MonitorMixin)
  • どうしてこう直したかという理由(Monitor is readable rather than MonitorMixin.)
  • どう直したか(変更点そのもの。diff)

私は、こっちのコードの方がいいんじゃないかということを伝える時には「どうしてそう思うか」という理由も伝えたいなぁと思っています。理由も伝えれば同じパターンの別のケースの時にも使える知識になってくれるのではないかと期待しているからです。そして、上述のようにコミットすることにより私が伝えたい内容を全部含んだ状態で伝えられるのではないかと思っています。ただ、これが本当に効果がある方法なのかどうかはまだわかっていません。

まだ、試行錯誤しているやり方ですが、コードに日本語や英語でコメントするよりも、コードでコメントするやり方をオススメしたいです。コードでコメントするということは、コメントをもらう側がわかりやすいコードでコメントしなければいけません。読む人のことをたくさん考えたコードを書く必要があります。コードでコメントをすることで、読む人のことを考えたコードを書くことがより当たり前のことになり、コメントのためのコードだけではなく、ふだん書くコードも読む人のことを考えたコードになったら、きっと信頼できるコードができるでしょう。

記事中でコードでコメントするやり方をしているのは、そんなことを期待しているからです。

DevLOVE Conference 2012のセッション「リーダブルコードを読んだ後」の紹介

るびまの記事ともつながるのでDevLOVE Conference 2012でのセッションも紹介します。

2012-12-16(日)にDevLOVE Conference 2012でリーダブルコードを読んだ後というセッションをします。このセッションは、今年の夏にやったリーダブルコードの企画のうち「リーダブルコードとはどのようなコードかを実際のコードを題材に考える」というワークショップ部分をもう一度やるセッションです*3。セッション概要を引用します。

リーダブルコードという読みやすいコード(リーダブルなコード)の書き方をわかりやすく説明した本があります。リーダブルコードに書かれているテクニックを使えばリーダブルな理解しやすいコードを書けるようになります。

しかし、リーダブルコードを読んだ人すべてがリーダブルなコードを書けるようになれるわけではありません。リーダブルコードに書かれていることを知識として持っているだけではリーダブルなコードは書けません。実際にその知識を使ってコードを書かなければリーダブルコードを読む前と同じようなコードばかり書くことになります。

このセッションはリーダブルコードに書かれていることを実際に使うためにはどうすればよいかということについてのセッションです。前半は講演者がどうすればよいかという話をします。後半は講演者と参加者で実際のコードを題材にリーダブルコードとはどういうコードなのかをディスカッションします。

るびまの記事の紹介のところでも「ベストプラクティスを知識として持っているだけではだめだ」ということを書いていましたが、このセッションでも「リーダブルコードに書かれていることを知識として持っているだけではリーダブルなコードは書けません」という点を問題としています。DevLOVE 2012のページに大きく「世界を変えるのは他の誰かではない、世界を変えるのは、自分自身だ。」とある通り、このセッションに参加したら「自分自身がリーダブルなコードを書いて世界を変えていく」ようになるようにセッションの準備を進めています。

ただ、実際にコードを読み書きしながらリーダブルなコードについて考えるのには50分の枠では時間が足りません。そのため、参加者には事前に以下のことをお願いする予定です。

  • リーダブルコードを読んでおくこと。 (リーダブルなコードについての基本的な知識を把握するため)
  • この記事で紹介している、るびまの記事「Ruby コードの感想戦 【第 1 回】 WikiR」を読んでおくこと。 (コードでコードにコメントをするやり方を把握するため)
  • git-utils/commit-email.rbを読んで、どこがリーダブルでどこがリーダブルではないかをるびまの記事にあるやり方で検討しておくこと。 (リハーサル。セッション内で初見でやるとリーダブルなコードについて考える時間がなくなるため。)

DevLOVE Conference 2012に参加しない人でも、リーダブルなコードに興味のある人はやってみてください。もう少し具体的な手順は以下の通りです。

  1. リーダブルコードを読む。
  2. Ruby コードの感想戦 【第 1 回】 WikiR」を読む。
  3. GitHubでclear-code/git-utilsをforkする。
  4. commit-email.rbを読んでリーダブルなところとリーダブルではないところを考える。
    • リーダブルなところがあったらコードのコメントに理由を書いてcommitする。
    • リーダブルではないところがあったら、るびまの記事でやっているように、よくなるように変更して、どうしてそれがよいかという理由をコミットメッセージに書いてcommitする。
    • ↑は1箇所につき1つのcommitにする。
    • 随時pushして誰でも見られるようにする。
    • まわりの人に↑のcommitについて意見を求めてみる。同意するとか自分はそうは思わないとかを聞いてみる。「まわりの人」は職場の人でもインターネット上で付き合いのある人でもどちらでもかまわない。

セッションが終わったら以下のようになることを期待しています。

  1. commit-email.rbだけではなく、自分がいま関わっているコードでもやる。
  2. 普段からリーダブルなコードを書く。
  3. どうしたらもっとリーダブルなコードになるかを考えながらコードを書く。

まとめ

るびま0040号の記事「Ruby コードの感想戦 【第 1 回】 WikiR」とDevLOVE Conference 2012でのセッション「リーダブルコードを読んだ後」を紹介しました。興味が湧いた人はまずはるびまの記事を読んでみてください。

おまけ(るびまの記事の感想):

*1 0031号るりまサーチの作り方 - Ruby 1.9 で groonga 使って全文検索以来なので約2年ぶり。

*2 この原稿用のリポジトリがGitHubにあることは記事中では触れていない。

*3 イベントページによると、すでに満席ですが増席を検討しているとのこと。

2012-11-26

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|