2010年10月9日土曜日

[.NET] C#ジェネリック IEnumerableの実装

小ネタですが、IEnumeratable(T)の実装についてです。
とりあえず、ソースコードです。

using System.Collections.Generic;
using System.Collections;

class MyClass<T> : IEnumerable<T>
{
    public int Count { get { return ...; } } //データの数
    public T this[int index]
    {
        get { return ...; } //indexを使ってデータを返す
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < Count; i++)
        {
            yield return this[i];
        }
    }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

IEnumeratorがジェネリックにも存在するので、変な記述に見えるのかもしれません。
混乱をさせるためにはusingを使わずにIEnumeratorを書けばよいかもしれません。

2010年4月20日火曜日

[PHP]ZendDebuggerからXdebugに乗り換えてみた

EclipsePDTと古いZendDebuggerの相性がよろしくなさそうなので、Xdebugに乗り換えてみました。Windows上でPHPのバージョンは都合により5.2を使ってます。

Xdebugのインストールは、xdebug.orgより適切なモジュール(DLL)をダウンロードします。DLLは、適当なフォルダにコピーした場合には、php.iniに「zend_extension_ts=<DLLのフルパス>」と指定し、PHPのextフォルダに入れたときには「DLLのファイル名」と指定すればよいです。

php.iniの設定はリモートデバッグを有効にするのと、リモートホストの設定だけでよいです。リモートホストの設定は1つだけしかできないようです。基本的にはローカルにあるサーバーにPHPとXdebugを入れてデバッグするという運用が想定されているものだと考えられます。

xdebug.remote_enable = On
xdebug.remote_host = localhost

リモートホストの設定は、XdebugとEclipseとの間の設定なので、Webサーバーがバーチャルホストでホスト名で参照してあっても、ローカルにあるならば「localhost」と書けばよいようです。
あとは、Eclipseのデバッグの設定で、サーバーのデバッガの設定を「XDebug」にして、「Break at First Line」はオフ(チェックしない)に設定したほうがよいようです。

基本的にはこれでデバッグできますが、Eclipseのデバッグの設定で、ファイルのmappingが正しくないとブレイクポイントで停止などの操作ができません。PHPサーバーの設定にあるPath Mappingのところにプロジェクトとサーバー上のファイルパスを設定すればよいです。
EclipseのプロジェクトがローカルWebサーバーのDocument Rootの配下あるならば、プロジェクトのファイルパスと同じになるはずので、Path on Serverのところはプロジェクトのファイルパスを手で入力すればよいでしょう。
もし、Path Mappingのところがうまくいかないときは、php.iniに「xdebug.remote_log=<ログファイルのフルパス>」を設定して、ブレイクポイントをどう設定しているかを確認してみるとよいようです。

あと、ZendDebuggerと違うところは、Xdebugの場合にはデバッグを開始するとセッションを張りっぱなしになります。そのため、1度デバッグを開始すればセッションを見失わない限りEclipseのデバッガと連動し続けます。
動きもXdebugのほうが軽いのですし、いまのところ安定して使えてます。ただ、変数の中身の表示され方がちょっと違ったりするのですが、慣れれば問題ないでしょう。

2010年3月28日日曜日

[PHP]とりあえず、CakePHPを使ってみる

CakePHPを使ってそれなりのものが作れるようになったので、CakePHPの基本的なことをまとめてみます。CakePHPのマニュアル(The Cookbook)を読んでいるというを前提に、ある程度スキルがある人向けな内容かもしれません。

インストール

マニュアル通りの手順でいけるはずです。強いていえば、apacheのディレクトリの設定で「AllowOverride All」にするのを忘れないことです。あと、app/webrootをドキュメントルートにせずにどこかのフォルダにマップして使いたいと思うかもしれませんが、できなくはないですが少々面倒なことになると思います。

Eclipse PDTで開発

最初はあまり凝ったことを考えずに、まず適当なフォルダにワークスペースを作って、そのなかにCakePHPに含まれているフォルダ(app,cake,venders)と同じ名前のPHPプロジェクトを作って、そのなかにそれぞれをインポートします。appプロジェクトにあるwebrootのディレクトリをドキュメントルートに設定されたバーチャルホストを作成すればよいでしょう。
なお、配布されているアーカイブの直下にあるファイルは見る必要はあるかもしれませんが、開発には必要ではありません。

開発を始める前に

ここで、開発に取りかかりたいところですが、まずはマニュアルの規約のところを読んだほうがよいです。CakePHPですばやく開発できるカラクリには、命名規約が大きく関わっているからです。

CakePHPのMVC

マニュアルのどこかにMVCの概念を使っていると記述されていたと思いますが、ターゲットとなるアプリケーションはデータベースを利用するWebアプリとなるはずなので、MVCのそれぞれは以下のようなものになると思います。一応説明しますが、軽く流してもらってよいです。

モデル
CakePHPのモデルは、テーブルにあるレコードにアクセスするためのクラスを意味します。もし、テーブルの仕様が規約にそっているならば、$nameがあれば十分ですが、カラムのルールとリレーションの定義もします。ルールは「Data Validation」の項、リレーションは「モデルを結びつける」の項を参照すればよいでしょう。
ビュー
ビューは、出力される形式(通常はHTML)を出力するPHPコード(拡張子ctp)を意味します。このコードではHTML全体を出力するのではなく、bodyに含まれる一部を出力します。外側はレイアウトで定義します。
コントローラ
コントローラは、ウェブサーバから来たリクエストを受け取って処理するところになります。基本的にはモデルからデータを取り出してビューに渡したり、フォームで入力されたデータをモデルを使って書き込むといった流れになります。

それぞれの関係について

あとは、規約にそってファイルを作成し、クラス定義もしくはコードを書いていくわけですが、それぞれの関係がわかってないとうまく動きません。それらを簡単に説明します。

コントローラとモデルの関係
モデルに対応するコントローラのオブジェクトには、モデルのオブジェクトが存在します($this-><モデル名>;)もしリレーションを定義しているのであれば、そのオブジェクトの中に関連付けされたモデルが存在します($this-><モデル名>-><関連しているモデル名>;)。それらのモデルのオブジェクトを使ってデータ(テーブルにあるレコード)を操作します。
コントローラとビューの関係
コントローラに定義するメソッドとビューのファイル名は規約により結びついていて、コントローラからビューにデータを渡すには、$this->set();を使って変数に設定してビューで参照ます。
ビューとモデルの関係
モデルでValidationを定義して、ビューでフォームヘルパー($form)を使って$form->input();で入力させるHTMLフォームを定義すると、ルールに合わないデータが入力されるとエラーが表示されるようになります。
リクエストとコントローラの関係
CakePHPでは、Webサーバ上でのリクエストは「/<コントロール名>[/<アクション名>[/<パラメタ>]]」となります。コントロール名はコントローラのファイル、クラス名に対応し、アクション名は、コントローラのメソッド名、ビューのファイル名に対応します。また、デフォルトのアクション名はindexです。
また、フォームで入力されたデータは$this->dataに格納されます。
コントローラとレイアウトの関係
コントローラの中で$this->layout変数かsetLayout();にレイアウト名を設定するとそれに対応するレイアウトのファイルが利用されます。
ビューとレイアウトの関係
レイアウトの中にレイアウト用に使われる変数($content_for_layoutなど)を出力するように定義します。ビューの出力などはそららの変数に入っています。詳しくはマニュアルを参照してください。

基本的な手順

開発の手順としては、まずテーブルを定義してモデルを作成します。既存テーブルを利用する場合には、モデルでカラムの定義が必要になるかもしれません。ただし、idとなるPRIMARYKEYがないとCakePHPでは操作できないようです。
あとは、操作しようとするモデルのコントローラとアクションとなるコントローラのメソッドとビューを作成します。まずはデフォルトのindex();メソッドとindex.ctpを作成するでしょう。
レイアウトは、必要最小限のものを/app/views/layouts/defualt.ctpに書いておいたほうがいいかもしれません。このとき、$html->css();で外部ファイルを読み込む場合には、webrootのcssフォルダを参照します。

2010年3月18日木曜日

[VC#] ClickOnceのマニフェストに署名するためのテスト用の証明書を作成する

VC#のプロジェクトのプロパティでClickOnceのテスト用証明書を作成することができるのですが、証明書の内容が気に入らない(発行者とか期限など)場合、別な方法で証明書を作成して読み込ますという話です。

まず、証明書を作成するためにmakecert.exeというツールが必要なのですが、Expressをインストールした場合には、存在しないようです。Windows SDKに含まれているのでインストールします。開発環境によりますが、現在のところ「Windows SDK for Windows Server 2008 and .NET Framework 3.5」というのをインストールするのがよいと思います。

まずは、makecertでpvkとcerファイルを作ります。makecertのコマンドオプションは、msdnのドキュメント等にありますので、詳細はそちらを読んでください。おそらく、最小限で必要なものは、以下のようになると思います。

makecert -r -pe -n "CN=MyCompany" -sv MyCA.pvk MyCA.cer

次に作成したpvkとcerファイルからpfxファイルを作ります。これはpvk2pfxというコマンドを使います。これもWindows SDKに含まれています。このコマンドを使ってClickOnceの証明書として取り込むpfxファイルを作るときには、1つ注意点があります。それは、-poオプションを使って、出力用のパスワードを設定しておくことです。pvk2pfxコマンドの実行例は以下の通り。

pvk2pfx -pvk MyCA.pvk -spc MyCA.cer -pfx MyCA.pfx -po "パスワード"

このコマンドを実行したときにパスワードの入力を求められますが、それはmakecertで作成したときのパスワードです。-poで設定したパスワードは、VC#などでファイルを取り込むときに求められるパスワードとなります。

取り込みが成功すれば、プロパティ表示の中にmakecert作成時に設定したオプションの内容が表示されます。

2010年3月10日水曜日

[.Net ミニメモ] DataGridViewにBindingSourceをバインドしたときに表示がおかしいとき

DataGridViewにBindingSourceをバインドして、同期して表示や編集をしているときに、列やセルの選択の表示がおかしくなっている場合があります。
そのときには、バインドしているBindingSourceを操作しているスレッドがメインスレッドになっているか確認してみてください。通常のUI部品への操作と違って、例外が発生せずにそのまま走りますが、動きが変になるようです。

具体的には、InvokeRequiredでメインスレッドでないかを確認して、必要であればInvoke()を使ってメインのスレッドで動くようにしてください。ありがちなC#のコードは以下ようなものです。

private void exampleHandler(object sender, EventArg e)
{
    if (InvokeRequired) {
        object[] args = { sender, e };
        Invoke(new EventHandler(exampleHandler), args);
        return;
    }
    // 以下に処理したいコードを書く
}

2010年2月16日火曜日

[ミニメモ] PHP5とMySQLのインストール

小ネタですが、忘れないようにメモしておきます。

WindowsでPHPでMySQLiとかのモジュールを利用するとき、MySQLにインストールされているライブラリを参照します。 そのため、MySQLがインストールされているフォルダにPathを通しておかないと、Apache起動時に失敗します。

具体的には、システムのPATH環境変数にMySQLのbinへのパスを追加して、Windowsを再起動します。