Category Archives: Code

テスト駆動開発の始め方


Test-Driven Development By Example (Kent Beck)
Kent Beck の Test-Driven Development By Example を Amazon で買う

約70ページにもわたって MONEY EXAMPLE という事例が書かれています。 あまりに多いので一気に読むのはちょっと辛いですが、テストドリブンを夢見てがんばって読んでいます。 今回は テストドリブンの序盤となる部分をyんでみました。

実装の前にテストをすべて書くのは無理

MONEY EXAMPLE のところを見ると、 Kent Beck ですら最初にすべてのコードを書かないということがわかります。 MONEY EXAMPLE で取り上げられている単純な金額の掛け算でも、コードが徐々に完成していくのにつれてテストコードも変わっていきます。 よく、最初にテストコードを書くなんて無理だからテスト駆動開発は無理だという人がいますが、テスト駆動とはそういうことではないんですね。

MONEY EXAMPLE では、 存在しないクラスを使ってテストを書き始めます。 Red どころか コンパイルすらできないテストを書くところから始めています。 必要なクラスを考えてクラスのテストから書き始めるのかと思いましたがそうではありませんでした。 最後の理想形をテストに書いていました。

テストドリブンの手順

ToDo の整理をしてからテストを始めます。 この ToDo List はコードが完成するまでついて回ります。 載っている事例では、 存在しない Dollar クラス を使ってテストを書くところから始めています。 そして テストを通してできるクラスのメソッドは(最初は)あくまでスタブです。

MONEY EXAMPLE は次のようにして進めていました。

  1. テストを書く。存在しないクラスも使ってよい。
  2. テストをコンパイルできるようにする。
  3. テストを Green にする。
  4. リファクタを行い、重複を取り除く。

テストを Green にする方法

  • 固定値を返すなどして、テストを通るようにする。 (実装コードとしては完成ではない)
  • 明らかにわかるコードを実装する。
  • 複数の側面からのテストを書く。 (Triangulation)

Triangulation というのは、 テストケースを追加することで固定値での返り値を返せないようにするように、複数のパターンのテストを書くことで実装コードを規定していく方法です。 たとえば 1 から n までの総和を求める関数があったとして、 Sum(1) == 1 だけだったら Sum の返り値は 固定の 1 でもいいですが、 Sum(5) == 15 だと実装せざるを得なくなります。 Kent Beck は本当にどのようにリファクタすればよいか迷うようなときに Triangulation を使うそうです。 どうすればいいのかわかっている場合は Triangulation のためのテストコードは書かれません。

MONEY EXAMPLE の中で出てきた Value Object というのも重要だと思うのでまとめておきます。

Value Object

一種のインスタンス変数で、コンストラクタで設定された値はそれ以降変わることがありません。 これにより、ポインタを通じた意図しない値の書き換えの発生を防ぎます。 別の言葉で書くなら 副作用対策です。

Value Object の持つメソッドの戻り値は必ず新しいオブジェクトにします。 下に例を書きました。 Numadd メソッドの戻り値は新しいインスタンスになっています。 これにより add の前後で Num のインスタンスは変更することがありません。 また、 primitive value ではないので、 別途 equal メソッドを実装しておかないとテストコードを書くときに困ることがあります。

Test-Driven Development By Example の JAVA のコードをまねて作ったのですが、 言語が ruby なので実践的には get_amount を書かずに attr_reader :amount と書きますね。

Test-Driven Development By Example (Kent Beck)
Kent Beck の Test-Driven Development By Example を Amazon で買う

Database available in FuelPHP


I wondered what database is available in FuelPHP, and look into FuelPHP code.

Environment

  • FuelPHP 1.8 (GitHub)

Available Database

The following DBMS is theoretically available in FuelPHP. It means that FuelPHP use driver for the following databases.

  • Cubrid
  • FreeTDS
  • Microsoft SQL Server
  • Sybase
  • Firebird
  • IBM DB2
  • IBM Informix Dynamic Server
  • MySQL
  • Oracle Call Interface
  • ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
  • PostgreSQL
  • SQLite 3, 2
  • SQL Azure
  • 4D

How to investigate

First, read manual. At the section Database Introduction, it says Can be mysql, mysqli or pdo. Namely, FuelPHP can handle mysql specific driver and PDO driver.

Then, read PDO section of PHP document. For above all DBMS, PDO is available.

Well, can FuelPHP handle PDO and connect to DB in real? Now, look at the FuelPHP core code, which handle database connection. There are 3 kind of connection.php, each of them handle mysql, mysqli, PDO connection. It’ll be clear PDO is available in FuelPHP.

Take your Attention when you use sqlite

You should be careful when you use sqlite. (FuelPHP version 1.7.2)

Primary Key

Migration doesn’t work when you add Primary Key like MySQL. In sqlite3, we can’t add name to Primary Key. 例えば MySQL なら Primary Key id (id) となるところが、 sqlite3 だと Primary Key (id) というようになります。

So, we should create plain SQL or change FuelPHP core code. It’s a choice not to use Primary Key, but I don’t recommend.

また通常は migration file を php oil を使って作成すると 自動で UNSIGNEDid が作成されて AUTO_INCREMENT が設定されますが、 sqlite ではこれが動きません。 sqlite では AUTO_INCREMENT ではなく AUTOINCREMENT になります。 いまのところ自動生成のスクリプトでは対応していませんので FuelPHP の core のコードを変更する必要があります。 そして自動生成される UNSIGNED は 削除しましょう。 sqlite では UNSIGNED BIT INT というのが使えますが、 使ったところで INTEGER と解釈されます。

Blank Charset

sqlite3 では charset の指定方法が他のデータベースとは異なります。 PRAGMA statement を使います。 (確か sqlite3 では標準文字コードが utf-8 だったと思います。)

If you don’t set charset in db config (config/db.php), php oil migrate occurs an error of SQL, CREATE TABLE, because SQL which contains DEFAULT CHARACTER SET utf8 at last is executed. To prevent that, set empty string to charset, charset => ''. すると、 DEFAULT から始まる文字コード指定部分がなくなり、 sqlite3 でも php oil migrate が動くようになります。

db.php は次のように書きます。

このようにすると、 環境ごとに別の DB が作成されます。 table_prefixphp oil r migration の時には不要ですが、 php oil r migration:down の時に必要になることがあります。

Take your Attention when you use PostgreSQL

Migration doesn’t work. It is because PostgreSQL SQL syntax is somehow different from MySQL one. I recommend you to use FuelPHP Plugin for PostgreSQL.


VBA: Output file list in a directory, recursively


This is the code I frequently use.

It recursively exports file list in a directory on Microsoft Office Application, like Excel. It is written in VBA.

VBA can be written in object oriented way, but I didn’t because I had to write the code as soon as possible.

Process Flow

  1. A user clicks the button on the sheet.
  2. The program show a folder browsing dialog.
  3. User chooses the folder, then the program make the list of file in the folder.
  4. The program exports the file list onto a form (or sheet).

To Do

  • Create a module file and create the following functions.
    • get file list
    • handle folder browsing dialog
  • Create a dialog to show the result.
  • Create a button on the sheet and add function on clicking.
Continue reading VBA: Output file list in a directory, recursively

How to Edit Remote Files on Local Computer


I will introduce the way to edit and save files at the remote server, on my local machine, and other alternative way.

Story

At the company, everyone develops the program on the remote server. Yes, it is Linux server with dark terminal, which provides only vim editor. The server can’t connect to public internet, so we need to upload tools with WinSCP from local machine if we want.

ローカルマシンで開発環境を構築するにも、いろんなチームが開発した多様なライブラリがないと動かないようになっていたため、ローカルマシンの環境を構築するのは困難な状況でした。 ファイアウォールの接続制限なんかもあって。

So I decided to edit remote files directly on the local machine, which can connect to the internet and install rich editors.

ここからは、リモートのファイルを(擬似的に)直接編集できるエディタを紹介していきます。

インストールすれば編集可能になるエディタ

まずは、インストールさえすれば編集可能になるエディタを紹介します。 プラグインなどの追加インストールは不要です。

NetBeans

IDE なら簡単にできるんじゃないかと思って トライしてみたのが NetBeans です。実際のところ、とても簡単に思い通りのことができました。

保存時に自動でリモートマシンに保存してくれます。シンタックスチェックもやってくれます。

既存のリモートマシンのファイルを元にプロジェクトを作成して進めていくこともできますし、新たにプロジェクトを作ってそこからリモートマシンにアップロードすることもできます。

やりかたは、 NetBeans のページで紹介されていますので、そちらをご覧ください。

参考: NetBeans IDEを使用するリモートWebサーバーへのPHPアプリケーションのデプロイ

Komodo Edit

Follow Edit, Preference, and you can configure remote server. After configuration, it can edit remote files.

reference: Basic settings to use Komodo Edit (removed: http://shimz.me/blog/editor/148)

gedit

After some configuration, it can edit remote files.

reference: Use Gedit as Remote File Editor via FTP and SSH (Ubuntu) (removed: http://thecodecentral.com/2010/04/02/use-gedit-as-remote-file-editor-via-ftp-and-ssh-ubuntu)

プラグインなどをインストールすることで編集可能になるエディタ

ここから下は 別途プラグインなどのインストールをすることで、リモートファイルが編集可能になるエディタです。

Eclipse

プラグインを使うと NetBeans と同じようなことができます。 プラグインは General Purpose Tool – Dynamic Languages Toolkit -Remote Development Support 。

参考: Eclipse Keplerで仮想環境上(リモート上)のファイルを編集する。

Sublime Text 2

It can edit remote files with SFTP plugin.

reference: Sublime text SFTPをつかってリモートファイルをローカルで快適に編集

It can edit remote files with rsub plugin, which requires the server to install something.

reference: リモートサーバー上のファイルをローカルのSublime Text 2で編集する (deleted)

Notepad++

It can edit remote file with NppFTP plugin.

reference: How to setup Notepad++ FTP plugin “NppFTP”

geany

geany はサポートしていません! ……が、 gnome だったら fuse を使えば ローカルマシンのようにリモートファイルを扱えるそうです。 これだと、 geany でなくても gnome なら どんな エディタ 使っても OK ですね。

reference: Does Geany support editing files remotely through FTP or SSH?

gVim

Windows マシン から、 PuTTY と連携して scp を使えるようにしようとしましたが、あえなく失敗。リモートマシンからファイルの一覧すら取得できませんでした。やり方を紹介しているサイトは多いのですが。

興味のある方は是非。

reference: vimからSSH/SCP接続してみる


Compare Groonga with SQL


I had to use groonga. The reason is simple, there is data only in groonga.

groonga も含め 全文検索エンジンを使うのは初めてだったので、 公式ドキュメントを見ながら探っていきました。 データベースで使用する SQL と groonga のクエリを比較してみると次のようになりました。 もともと別物なので参考程度に見ていただければと思います。

SELECT

We use SELECT to get some data from groonga, also from database. But there’s considerable difference between the structure of data between groonga and database. As for groonga, sql command is like the following.

Simple comparison is as follows.

Database groonga
表示カラム (listed after select) ––output_columns
Table from ––table
Search Condition where ––filter, ––query, ––match_column, ––scorer
Order order by ––sortby
Offset offset ––offset
Limit limit ––limit
Group group by ––drilldown (drilldown したときの件数指定などは下の説明を参照)
Logical Operator and, or &&, ||

Supplemental Explanation

––output_columns

検索結果に表示するカラムを指定する。カンマで区切ることにより、複数カラムを指定できる。

––query

全文検索を行う。

title カラムについて 文字列 “this” の全文検索を行う。

––match_columns, ––query

検索結果に含めるカラムを指定する。複数指定もできる。

––query と一緒に使い、 title カラムについて 文字列 “this” の全文検索を行う。

––filter

Specify query condition. Likewise javascript, we can use operator “==”, “<=“, “>”, etc. AND, OR should be represented as &&, ||.

––drilldown

バージョン4.0.1 の資料を見るかぎり、 drilldown に指定したそれぞれのカラムについてグループ化した結果が表示される。 column_1 と column_2 を指定していれば、 column_1 だけでグループ化した結果と、 column_2 でグループ化した結果が続けて表示される。 ORDER BY column_1, column_2 のようなことはできない。

drilldown の結果に対する件数指定(オフセットなど)は下記のように、 通常の ––sortby, ––offset, ––limit の頭に drilldown をつけて指定する。 drilldown した結果だけがほしければ、 ––limit0 を指定して出てくる通常カラムを制限する。

Specific Column

Column Name Description
_id ID column whose is generated by groonga automatically in query.
_key The column which contains primary key.
_score Virtual column in query result. (Likewise ROWNUM in Oracle DB.) It has higher number if the record matches to query condition more.
_nsubrecs The column which contains query drilldown result number when drilldown is used. It’s like COUNT function in SELECT COUNT(1) FROM ….