2012-07-31

JICA WORLD REPORTER #7

JICAワールドレポーター更新。
多事多端


最近、ホントに活動(仕事?)が忙しい...そんなでこのブログも投稿が滞りがち。週末の予定は全てキャンセル、平日も毎晩2時くらいまで家で仕事をしてる。ここ2ヶ月間で出かけたのは平日の夜に外食に3回行っただけという引きこもり具合。万国共通でこの業界(IT系)は納期前になるとどうしてもこうなってしまうのか、自分のやり方が悪いのか、何だか日本で仕事をしていたときのようになってきた。

とはいえ配属先から納期や残業をとやかく言われているわけではなく、今まで自分で決めた納期を守れずズルズルと延長してきた自分に嫌気がさし、覚悟を決めてやってるわけなのだが...それにしてもやらなきゃならないことが多過ぎる。こんなに働いてるJICAボランティアは世界中探しても他に居ないんじゃないかなと思う。

こんな状況が9月末までは続きそう(というか、その頃までには終わらせたい...)。

開発環境のご紹介

朝9時に出社して昼休みに家に戻って1時間弱仮眠して、また職場に戻って6時頃に帰宅。その後は夕飯を食べてから2時くらいまで仕事をしてシャワー浴びて寝る。仕事中は独り黙々とコーディングしているだけ。そんな毎日の繰り返しなのでブログネタがないというのが正直なところ。というわけで、今回は同職種(同業者)向けに開発環境のご紹介。何という内輪ネタ(苦笑)。

開発概要:
ドミニカ国の保健情報を統合管理するWebサイトの構築

  • サーバー: Ubuntu 12.0.4 LTS
  • Webサーバー: Apache 2.2
  • DB: MySQL 5.5
  • 言語: PHP 5.3, Twig, Ajax(jQuery)
  • フレームワーク: Symfony2
  • 主要追加バンドル: StofDoctrineExtensionsBundle, DoctrineFixturesBundle, JMSSecurityBundle, KnpPaginatorBundle
  • ツール, モジュール: Google Maps API, FPDF, Spreadsheet_Excel_Writer
  • テストフレームワーク: PHP Unit, Stagehand_TestRunner
  • ソース管理: Git, git-flow, GitHub

こうして見るだけでも色んな知識が必要なのが分かる。しかも日本で仕事してた時よりはるかに最新の開発環境。ちなみに要求定義~設計~コーディング~テストまで全て独りです。根っからのソフト開発屋なのでWebの画面デザインとかあまり得意じゃないんだけどな...

2012-07-02

NetBeans で PHPUnit を使う際の注意

NetBeans 上で PHPUnit が使えるのは非常に便利だが、その際にNamespace を用いているクラスの場合、名前解決に結構クセがありハマったのでメモ。
以下いくつか注意点を列挙。

PHPUnitフレームワーククラス自体の名前解決

当然ながらテストクラスはnamespace宣言により、テスト対象クラスの名前空間になっているので、継承時にPHPUnit_Framework_TestCaseだけではダメで最初に"\" が必要。サイトや書籍のサンプルを試すときは要注意(テストクラス自動生成時は既に追加されている)。
namespace Hoge\Moge;
class SomeClassTest extends \PHPUnit_Framework_TestCase 
{
}

クラス読み込み(require_once)

テストで使用するクラスはモックを使用する場合でも全て読み込みをする必要がある。 通常テスト対象クラスとテストクラスはディレクトリが異なるので(例えばsrcとtestsのように)、そこまでのパスを相対指定する。
namespace Hoge\Moge;
require_once __DIR__ . '/../../../src/Hoge/Fuga/AnotherClass.php';

ただし、この方法だと階層が深いと読みづらい上に、使用クラスが多くなると大変。bootstrap.phpを用意してauto_loadを実装したクラスローダークラス等を先に読み込ませた方がスマート。
その場合は、プロジェクトのプロパティ>PHPUnitカテゴリーのUse Bootstrapにチェックしてファイルを指定するか、require_onceで読み込ませる。
namespace Hoge\Moge;
require_once __DIR__ . '/../../bootstrap.php';

この方法だと使用クラスが増えた際も、その都度個別のファイルを指定する必要がなく便利。

クラスインスタンス生成

通常のクラスインスタンス生成はuseキーワードを追加することで、ショート名を用いることができる。
namespace Hoge\Moge;
require_once __DIR__ . '/../../bootstrap.php';

use Hoge\Fuga\AnotherClass;

class SomeClassTest extends \PHPUnit_Framework_TestCase
{
    public function testMethod() {
        $class = new AnotherClass();
    }
}

モック生成時のクラス名指定

問題はモックを使用する場合で、requireで個別にファイルを読み込ませたか、クラスローダーに読み込ませたかに関わらず完全修飾名で指定する必要がある。
namespace Hoge\Moge;
require_once __DIR__ . '/../../bootstrap.php';

use Hoge\Fuga\AnotherClass;

class SomeClassTest extends \PHPUnit_Framework_TestCase
{
    public function testMethodNotUseMock() {
        $class = new AnotherClass();
        $this->assertEquals('foo', $class->doSomething());
    } 

    public function testMethodUseMock() {
        $stub = $this->getMock('Hoge\Fuga\AnotherClass');

        $stub->expects($this->any())
               ->method('doSomething')
               ->will($this->returnValue('foo');

        $this->assertEquals('foo', $stub->doSomething());
    }
}

なぜか、PHPUnitに渡すクラス名の場合、名前解決は完全修飾名ではないとダメな模様。自分は、これに引っ掛かって相当時間を費やした。もしかしたら設定で指定できるのかもしれないが、とりあえずこれでも解決。

Abstract クラス
抽象クラスのモックインスタンス生成はgetMockForAbstractClassを使う(抽象クラスはそもそもgetMockではインスタンス生成できない)。その際、具象メソッドはメソッド上書きの対象にならないので注意。抽象クラス上の具象メソッドを偽装させたい時は一度その抽象クラスを継承したクラスを宣言した上で、そのクラスをgetMockで上書きする必要がある。
// AbstractClass.php
abstract class AbstractClass
{
    public function notOverridable() {
        return 'hoge';
    }

    public function concrete() {
        $this->overridable();
    }
     public abstract function overridable();
}

-------------------------
// AbstractClassTest.php
class ConcreteClass extends Abstracrt
{
    public function overridable() {
        return 'fuga';
    }
}

class AbstractedClassTest
{
    public function testAbstractMethod() {
        $stub = $this->getMockForAbstractClass('AbstractClass');
        $stub->expects($this->array())
             ->method('overridable')
             ->will($this->returnValue('moge');

        // abstractメソッド(overridable()) は上書き(実装)される
        $this->assertEquals('moge', $stub->concrete());
    }

    public function testConcreteMethod() {
        $stub = $this->getMockForAbstractClass('AbstractClass');
        $stub->expects($this->array())
             ->method('notOverridable')
             ->will($this->returnValue('moge');

        // 具象関数 notOverridable は上書きされず 'hoge'が返される(アサート発生)
        $this->assertEquals('moge', $stub->notOverridable());
    }

    public function testOverridedConcreteMethod() {
        $stub = $this->getMock('ConcreteClass');
        $stub->expects($this->array())
             ->method('notOverridable')
             ->will($this->returnValue('moge');

         // ようやく overridable()  は上書き(実装)される
         $this->assertEquals('moge', $stub->notOverridable());
     }
}

もっともこのように抽象クラスの具象メソッドを偽装させたい時に、テストクラス側に抽象クラスのサブクラスを記述しなければならないのであれば、あまりgetMock系メソッドの恩恵は少ないように感じなくもないが、それでもなお各テストメソッドにおいて動的に返り値を指定できるというメリットは大きい。

2012-06-19

Waitukubuli National Trail Seg. 2 - PUBLIC SERVICE DAY ACTIVITY

I have uploaded a short movie 'Waitukubuli National Trail Seg. 2 - PUBLIC SERVICE DAY ACTIVITY' I made to my Photo Blog 'photoconuts' and Vimeo.  enjoy!
 
WNT Seg. 2 - PUBLIC SERVICE DAY ACTIVITY from toconuts on Vimeo.

2012-06-16

github 導入2 - リポジトリ作成編

github にリポジトリ作成

github のサイト右上の Create a New Repo をクリック
プロジェクト名を入力して作成。

※ Initialize this repository with a README のチェックは外しておく。
チェックしたまま作成すると、下記の手順ではpush時にreject される。
その場合は git fetch 後 git merge origin/master を実行すればOK。

ローカルにリポジトリ作成

$ mkdir test
$ cd test
$ git init
$ touch README
$ git add README
$ git commit -m 'first commit'
$ git remote add origin https://github.com/username/test.git
$ git push -u origin master

push時にgithubに登録したユーザー名とパスワードを入力
以降は既存のファイルを編集したり、新たにファイルを追加したり際には、 add > commit > push  を繰り返す
既存ファイルの編集だけで、新たに追加したファイルがない場合は"-a"オプションをつけてcommitを実行すればaddを省略することができる。
$ git commit -a -m 'modified'

SSHで接続するにはリモート追加時に下記のように記載する
$ git remote add origin git@github.com:username/test.git

README.md の編集

Markdown 文法については下記サイトを参照

リポジトリ内のファイル操作

ファイル名変更 (README からREADME.md に変更)
$ git mv README README.md

ファイル削除(README.mdを削除)
$ git rm README.md

コミット前に削除を取り消し
$ git reset HEAD -- README.md
$ git checkout -- README.md

ファイル名変更、ファイル削除のいずれの場合も commit でリポジトリに反映
$ git commit -m 'comment'

コミット前にステータスを確認するには
$ git status

2012-06-15

github 導入1 - 設定編

gitのダウンロードとインストール

Ubuntuの場合
$ sudo apt-get install git-core
他の環境はこちらを参照
git - downloads

gitの設定

デフォルトユーザー名とEメールアドレス
$ git config --global user.name "Your Name Here"
$ git config --global user.email "your_email@youremail.com"

これらは個別のリポの設定で上書きすることもできる
$ cd my_other_repo
$ git config user.name "Different Name"
$ git config user.email "differentmail@email.com"

HTTPSでのPassword caching の使用とタイムアウトの指定(秒: デフォルト15分)
$ git config --global credential.helper chache
$ git config --gllbal credential.helper 'cache --timeout=3600'

設定の確認
$ cat ~/.gitconfig


※以下はgithubとの接続にSSHを用いる場合のみ設定が必要。Httpsで接続するのであれば上の設定だけで良い(こちらがgithub推奨)

SSH鍵の作成と登録

既存の鍵の確認
$ cd ~/.ssh
$ ls

.ssh ディレクトリが既に作成されていて、そこにid_rsa と id_rsa.pubがあればそれを使うこともできる。その場合は「公開鍵のコピー」までスキップ

既存の鍵のバックアップ
$ mkdir key_backup
$ cp id_rsa* key_backup
$ rm id_rsa*

鍵の生成
$ ssh-keygen -t rsa -C "your_email@youremail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (home/user/.ssh/id_rsa): [just press enter]
Enter passphrase (empty for no passphrase): [Type a passphrase]
Enter same passphrase again: [Type a passphrase]

公開鍵のコピー
$ xclip -sel clip < ~/.ssh/id_rsa.pub

xclipがインストールされていない場合は先にインストール
$ sudo apt-get install xclip

公開鍵の登録

githubのサイト右上のAccount Settingsをクリック
左のサイドバーのSSH Keysをクリック
Add SSH keyをクリック
Keyフィールドにペースト

2012-06-14

Flower - movie version

Uploaded a short film I edited about Dominican style of flower arrangement.
enjoy!!!

Flower from toconuts on Vimeo.

2012-06-11

JICA WORLD REPORTER #6

JICAワールドレポーター更新。
訪問者


 我々ボランティアが持てるパスポートは普通のパスポートとは違いオフィシャルパスポートと呼ばれている。国交がある国であればどこにでも行ける通常のパスポートとは異なり、青年海外協力隊員に限っていえば、渡航できる国はかなり制限されている。

加えてJICAでも独自に任国以外に旅行できる先を制限している。そのためドミニカを訪問できる国はかなり限られている。

2つ下(南)の島St. Luciaもそんな数少ないドミニカに渡航できる国の一つである。そのSt. Luciaの隊員から、あちらに住む台湾ボランティアがドミニカを訪問するのでその際のアテンドをして欲しいと頼まれ、先日、Whit Mondayのホリデーを含めた4日間の日程で来ドミした。


ドミニカを満喫してもらうべく連日朝から晩まで色々なところに案内した。
参考までに今回の日程は下記の通り。
  • Day1 - 首都ロゾー市内観光 - Scotts Head - ドミニカ最南端の陸続きの島 - Champagne Beach - 海中からシャンペンの泡のように吹き出ているビーチ - Fort Young ホテル(ハッピーアワー) - Jazz 'n Creolイベント 
  • Day2 (一日バス貸切り) - Middleham Falls - 壮大な滝壺のある滝 - Titou Gorge Falls - パイレーツカリビアンでも使われた洞窟内の滝 - Trafalgar Falls - ファザー、マザーと呼ばれる二つの滝と天然温泉 - Screw's Spa - 個人的にドミニカ一と思う温泉
  • Day3 (一日バス貸切り) - Chaudiere Pool (Bense) - 高さ5m位の崖の上から滝壺にダイブできる川 - バーベキュー No.1 Beach (Calibishie) - Cabrits National Park - Jazz 'N Creole メインイベント
  • Day4 (一日バス貸切り) - Glasse - 岩場に穴が空いていてそこがプールになっている海岸 - Melville Hall Airport(見送り)

こうやって予定を見直すだけでもかなりハードな4日間だったと今更ながら思う。正直なところ自分もかなり疲れた。


ゲストの台湾ボランティアに加え、米国Peace Corps、フランス、オーストラリアのボランティア、ロスユニ(米大学ドミニカキャンパス)の学生、もちろん地元ドミニカ人などに声をかけ、結果かなりの人数に集まってもらえ、どれも多国籍なイベントとなった。果たしてドミニカを楽しんでもらえただろうか...

ドミニカ在住のJICAボランティアが少なくなったせいか、最近こういうことでもないとタクシーをチャーターしてどこかに出かけることはめっきり減った。その意味でも我々ドミニカ ボランティアにとっても良い機会だったと思う。

余談だが、聞くところによると、ここドミニカにもかつては台湾ボランティアが農村部を中心に入っていたが、現政権になり中国中心の政策への転換がなされた結果、台湾ボランティアは全て追い出されてしまったらしい。中国の支援は多額の資金を投入し、人員も本国から連れてきて、いわゆる箱物や道路などの建設を行っている。そのため、ドミニカを大規模に開発することを嫌う人々からは批判的な意見を聞くことも多い。一方、農家に対する人的貢献等を行っていた台湾ボランティアに対しては、「あの頃は良かった」のような昔を懐かしむ声を聞くこともある。ここ遠く離れたドミニカでこうした中国-台湾の問題を垣間見るとは思いもしなかった。

2012-06-07

【備忘】 Utuntu11.04にXdebugをインストール


eclipse PDTやNetbeansでデバッグ実行するためのXdebugの導入手順。

1 Xdebug
$ sudo apt-get install php5-xdebug

2 設定ファイルに追記
$sudo gedit /etc/php5/apache2/conf.d/xdebug.ini

zend_extension=/usr/lib/php5/20090626/xdebug.so
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000

3 Apatche 再起動
$ sudo /etc/init.d/apache2 restart


2012-05-09

JICA WORLD REPORTER #5

JICAワールドレポーター更新。
活動報告会



先日、JICAドミニカ共和国事務所長がここドミニカ国(紛らわしい...)を訪問された際に活動報告会が開かれた。

ドミニカ共和国事務所は、この辺りのカリブ地域を統括しており、ドミニカ国にはない機関、例えば健康管理員の方等は、ドミニカ共和国の健康管理員の方が兼務していたりするため、隊員も何かと相談したりで利用したりする機会が多い事務所である。


今回の報告会では、一人10~15分程度で、活動計画書に沿った形で、現在の進捗状況や今後の課題等を報告するという形で行われた。当初この話が持ち出された時には、隊員の多くは「え~、そんなに話すことはない」なんて言っていたが、いざ本番となれば全員が持ち時間オーバーで、しかもまだまだ話し足りないという感じだった。やはり各自それなりに思うことが溜まっていたのだろう。ドミニカの現在の隊員は最低でも一年以上はここで活動を続けている人たちなので、活動において悩んだり、自分なりに工夫したり努力したりすることも少なくはなかったはず。


今思えば、隊員全員が発表するという場はある意味新鮮だった。もちろん各自の中間報告会(着任後1年経過時)であったり、最終報告会(帰国直前)であったりで話を聞くことはあったが、こうして全員が発表するという機会は、自分が着任後一度もなかったのではないかと思う。

ここドミニカの隊員は首都ロゾーに集中しており、いずれも徒歩圏なので会おうと思えばいつでも会える。そのため、今現在どんな活動をしているのかについては何かと話したり聞いたりする機会も多い。そんな感じだから、他の隊員のひとつひとつの活動内容については何となく知っている気がするのだが、逆に、その隊員の活動の全体像やその活動を行う意義については、実はこれまであまり知らなかったんだな、ということを痛感した。

2012-04-19

JICA WORLD REPORTER #4

JICAワールドレポーター更新。
中間報告会


ドミニカに来て早一年、先日、JICA、配属先、そして隊員(自分)の三者による中間報告会が行われた。前回までの中間報告会はホテルで大勢を呼んで発表の場としての意味合いが強かったが、今回からはもう少し忌憚のない協議の場としたいとの意図からJICA事務所にて関係者だけで設けられた。そのせいもあってか、終始リラックスしたムードで深い議論がなされたように思う。

前にも書いたが自分の活動内容は大きく分けると3つある。
  1. 現在あるスタンドアロンの保健関連の情報システムを、国内の病院・診療所からアクセス可能なWebシステムとして再構築する
  2. 先代JICAボランティア(自分で4代目)がこれまで構築してきたシステムのメンテナンス
  3. 3. その他、職業柄依頼されること(例えば、ウィルス駆除、PC修理やデータ入力支援ツールの作成等)
このうちの2,3は特に問題ないが、主たる活動である1の作業の進捗が、自分で立てた計画に対し大幅に遅れをとってしまっている。その原因はいくつかあるが、一番は自分が立てた計画上の工数見積もりにだいぶ考慮漏れがあったことであろう。
ユーザー管理、メンテナンス、ログ出力、バックアップ、セキュリティといった現行システムに備わっていない機能の追加や、サーバー環境の設計(使用言語、アプリケーションサーバーやサードパーティーのモジュールの選定)及びその構築など、当然といえば当然だが、1人だけが使う事を想定して作られている現在のスタンドアロンのアプリケーションから単なる環境移行というわけにはいかない。今有る機能、無い機能にかかわらず全て一から作る必要がある。正直、一人で全部を行うには作業が多すぎる。また、自分自身の生産性の低下、すなわち、勤務時間が日本に比べて短く、加えて調べものをするにも、ドキュメント読むにも、メール等で報告書を書くにも、英語のため何かと時間がかかるということも考慮に入れる必要があった。

もっとも、この点については、この中間報告会に先立って配属先と事前会議をして、現状の進捗状況、問題点及びその解決策について議論し、リスケジュールも決定してあったので本報告会では、その内容の確認程度に留まった。

それより中間報告会での一番の収穫は、自分の活動の意義をもっと大きな視野で俯瞰できたことであろう。「貧困対策」、これはJICAおよび我々ボランティアの一番の柱であるはずなのに、とかく今の配属先でこうした活動を行っている限り、そのようなものを感じさせる場に出会わすことは皆無に等しく、その言葉を忘れかけていた。

確かにドミニカにもカリブ地域(先住民族であるカリブ族が住む独立自治のテリトリー)など、経済的弱者が多く住む地域が存在する。首都の病院にはバス代がなくて行けないなんて話も聞く(片道300円前後)。配属先が目指す全国どこからでもアクセス可能な医療関連情報システムが構築されることにより、今まで中央にしか集まらなかった各種有益な情報に地方の小さな診療所からでもアクセスし閲覧することが可能となる。それにより、疫病流行時の早期対策や医療水準の全体的な向上などが期待できる。

得てして、経済的弱者は持てる情報も少ないことが多い。また情報の質といった面でも正確さを欠く間違った情報を与えられていたりすることも多い。全国どこからでもアクセス可能な医療関連情報システムの構築は、こうした情報格差をなくすことに寄与する。そのシステムの一部を自分が築くと思うと俄然ヤル気が湧いてくる。

 
Copyright 2010 toconuts. Powered by Blogger Blogger Templates create by Deluxe Templates. WP by Masterplan