2010年12月26日日曜日

Rails3でModel.allなどのデフォルトのソート値を変えたい

default_scopeとnamed_scopeを使う

default_scopeは使い方には注意が必要です。publishedをdefault_scopeでやってしまうと、管理画面などで非公開中の記事も含めた結果を得たい場合に無駄なコードが発生しまいます。それよりはnamed_scopeを使った方がいいし、メソッド名がさらに何をしているかを分かりやすくしてくれます。

元記事はRyan's Scraps - What's New in Edge Rails: Default Scoping

CakePHPではdefault_scopeと同じことはできますが、named_scopeは今もメソッドを用意するのがベストプラクティスなんじゃないでしょうか。もっといいやり方知ってるよーって方は教えて下さいm(_ _)m。この記事おすすめです。Sooey - CakePHPを使ったMVC設計のベストプラクティス

2010年12月24日金曜日

Rails3 Ruby1.9.2でGmailを使う時はtlsmailは必要ない罠

tlsmailをrequireするとmail 2.2.13からエラーが出て起動しなくなる

`remove_method': method `tlsconnect' not defined in Net::SMTP (NameError)

このエラーのせいで立ち上がらない><

そもそもtlsmailが要らないというオチ

普通にこうかいたらできました...

2010年12月18日土曜日

Redmineは鋭意開発中

今後のリリースプランが発表されました

Plans for next Redmine releases

1.1は何週か後にリリース予定。1.2ではこれまでに要望が多かったチケットに関する機能の強化、1.3でも要望が多かった機能を実装していく予定で、具体的にどのような機能を予定しているかも書かれています。

前回の、「Redmine開発がちょっとヤバイぞ」が意外にアクセスがあったので、不安を煽ってすみませんm(_ _)mということで、速報記事でした。w

2010年12月17日金曜日

Rails3でDeviseを2つ使ってみる

Deviseは認証系

Deviseを使うと、メールでのアクティベーションとか次回ログイン省略とか、TwitterだOpenIDらもできる?(ここまで入れるとOmniAuthになるんかな?) WardenベースのRails以外でも使える認証系ライブラリです。githubにあります。

使い方とかはgithubにあるwikiやrailscastsやREADMEを翻訳してくれてるサイトにまかせて、今回はあまりやらないであろうマイナーチャレンジとして、deviseを2回使ってみましたw

ユーザと管理者を別モデルにしたいじゃんというお話

rails g devise MODEL でいくつも作れるので特にdeviseの最初から書かれてあるオプション通りであれば問題はないのですが、どれかだけ認証の方法をメール+パスワードから別のものに変えたいという場合や、複数のdeviseでログイン成功後のリダイレクトの先を変えたいというニーズはあって普通と思うし、後者はwikiに書かれてました。前者はあるのか知らないけど、MLで質問したら教えてもらったのでせっかくですのでブログに残しておきます。(前置き長い)

UserモデルとAdminモデルで認証方法を変える

やり方は簡単で

  • 認証方法を変えたいモデルでクラスマクロdeviseで:authentication_keys => [:foo]
class Admin < ActiveRecord::Base
  devise :authentication_keys => [ :name ]
end
と書けばOK。:passwordを書くとエラーが起きるので書かない。もしリダイレクト先を変えたければ、routesとapplication_controllerで制御する方法がgithub上のwikiに載っているのでそちらを参照

Deviseのお陰で認証部分をほとんと作らずに済んでかなり助かってます。が、viewは簡単に操作できるからいいとして、認証まわりは結構隠蔽されていて分からない。今後は日本の携帯デバイスなど、PCブラウザ以外のところで問題が起きた時が厄介そうだと思いつつも、MLは活発で質問したらすぐに返答が来たので、今後も使って行きたいところ。

2010年12月13日月曜日

Rails3で国際化とデフォルトロケール設定と日本語をコード内で使うことと

# encoding: UTF-8をline:1に書かないとinvalid multibyte char (US-ASCII)

Viewファイル内では普通に日本語が使えるのに、コントローラとかじゃ使えないじゃん!ということになる。RailsじゃなくてRuby1.9からエンコーディングの指定方法が変わったからかな?UTF-8なら書かなくても動くと思ってたけど...とにかく動かないよー(T_T)という時はマジックコメント。

デフォルトロケール設定

$RAILS_ROOT/app/config/application.rb

config.i18n.default_locale = :ja

ActiveRecordなどのエラーで、翻訳がないというエラーが出るようになるので、心の準備はしておきましょう。(翻訳作業が発生します。)

2010年12月2日木曜日

Redmine開発がちょっとヤバイぞ

Eric Davisが開発から身を引いた

Stepping Down From Redmine

Redmineの作者Jean-Philippe Langが途中いなくなった時期があったんですが、最近やっと復活したようですね。でも残念なお知らせ、コアディベロッパーのEricさんが開発から身を引くそうです。Ericさんがいなかった時期も、Redmineはきちんと開発されてきたけど、Ericさんが入ってからもっとよくなったという印象が個人的にあるために残念。しかも身を引く理由の本当の部分を明らかにしてないけど、どうも内部でもめてる様子。

Railsのバージョンはまだ2.3.5で止まったままだし、Ruby1.9.2に対応するには書き直す部分もありそうで、結構ふくれあがって来てると思う。そんな時に組織が崩壊し始めたら死んじゃうんじゃないだろうか。と、ちょっと不安。Redmineを超える新しいツールが出るといいけどね。作るか?って話をしてる人たちもちらほらいそうだ。

2010年12月1日水曜日

RailsをUnicornで動かしてみる

Redmineを動かしてみた

Apache + Passenger (REEで)は、起動中は素晴らしいパフォーマンスを出してくれるけど、一旦落ちると、起動するのに時間かかるし、デプロイするときに再起動しないといけない。再起動はapacheではなく、Passengerがtmp/restart.txtが生成されたタイミングでアプリを再起動してくれるからいいっちゃいいんですが、unicornはその辺もOK!と。そしてよく分からないfork型?とにもかくにも、unicornを知ってもう一年!一回くらいは試しておこうと思ってやってみました。そのうちnginxとの組み合わせもやります。

unicornのインストール

gem install unicorn

Rails2.3.5はRack1.0.4を使う

1.0.4だったっけかな?忘れましたが、1.2とか上のバージョンのが入ってると動いてくれません。アンインストールする必要があります。Rails3はRack1.2でも動きます。

起動の仕方は簡単で、RAILSアプリのルートフォルダで

unicorn_rails -D -E production
という感じです。Dオプションはデーモン、Eは環境、デフォルトはdevelopment、-cで設定ファイルのパスを渡すこともできます。

unicornは起動に失敗しても永遠と起動しようと努力するので、ちょっとその執念深さが怖かったのですw

気になるパフォーマンスは

ちゃんと取ってないけど、Passengerの方が若干早いかなという感じ(2ミリ秒くらいw)で、差はそんなにない感じです。nginxと組み合わせて、Apache + Passengerと比べてどうなるかは分かりませんが、きっとそんなにパフォーマンスに差はないんじゃないかなーと思います。なんせRedmineを3人くらいで使ってるので。これが大規模サイトになれば違うんでしょうね。githubがunicornで動いてるんじゃなかったかな?githubの中にはちゃんとチューナーがいそうなので、うまくまわってるんでしょう。

2010年11月25日木曜日

Smarty3がリリースされたようなので、いいところを紹介しよう

よりオブジェクト指向&高速になったSmarty3

PHP5でパーサーを一新されました。いきなり話は変わりますがw、PHP5.2からはオブジェクト指向で書いても速いし、PHP4より性能も良いので、未だにPHP4を使ってるのであれば移行しましょう。今は良くてもそのうち負債になりますよ。そしてその時は是非Smarty3を一足先に導入して人柱になってくださいね♪

Smartyふたたび

Smartyは、なぜか一時期(今も?)嫌われていましたが、個人的には使い方によっては生のPHPを使うより全然良いと思います。SmartyはHTMLのためのテンプレートエンジンとして使ってる人が多いかもしれませんが、テンプレートエンジンなので、例えば他のところでも変数展開を使いたい場面では使えます。例えば、定型型メール、テーマ別CSS、サーバ側で動的なデータを反映させたJavaScriptなど、意外にいろいろと使い道はあるんです。

Smarty3を使ってみて2にくらべて良いなーと思った点をあげてみます。あ、もしかしたら1に比べてかも...

  • nocacheがすこぶる便利
  • テンプレート内にJavaScriptを書くのが簡単になった
  • ファイル以外のテンプレートデータも扱える
  • 全米が泣いたフィルタの便利さ

他にも気付いたSmarty3のいい点があれば、また後日書くとして、上の4つはいいですよ!

nocache

例えば、ページ内の一部はキャッシュせず毎回その時のデータを入れたいとか。時刻くらいならJavaScriptでクライアントサイドでやっちまえよって話なんですが、そうでない時に便利です。Ajaxでほとんどいけるけど... キャッシュファイルにもPHPコードが残っておいてくれてるっていうことで、変数つっこんで使えるってのが便利なんすよ!!例えばJavaScriptを使わず、メール本文のテンプレートに使うときとか、トークンとかね!便利そうでしょ?便利ですよ!!

JavaScriptを書くのが簡単になった

HTML内部にJavaScriptを書くことを推奨しているわけじゃないですよ。でも時にJavaScriptを動的に生成したい時がありますよね?そういう時に便利です。JavaScriptもSmartyテンプレートで書いた事があります。静的ファイルじゃないといけないって誰が決めたんですかっ!?(切れ気味)

ちなみになぜ簡単になったかというと、デリミタが直後に空白を許さなくなったからです。正直literalで囲ったところでsmartyの変数を展開するのは面倒臭すぎたのです。でも今はliteralを使うケースは最小限に食い止められますよ!

ファイル以外のテンプレートデータも扱える

ごめん。詳しくはググって。きっとテンプレートデータをDBに持つか、ファイルに持つか、変数に持つかの違いだけど、そこを簡単に扱えるようにしてくれたんじゃないかな?(疑問形)

全米が泣いたフィルタの便利さ

あなたはCakePHPのビューファイル内でh関数を通すのに嫌気が差したことがないだろうか。CakePHPのこと詳しくないから知らないけど、生PHPだとエスケープ処理を必要なだけ通さないとといけません。もしエスケープ処理の方が圧倒的に多いのであれば、Smarty3でエスケープをデフォルトにする方法をご参考にどうぞ。しかし注意!その記事のやり方でも動きますが、正しいやり方は「$smarty->registerFilter('variable','htmlspecialchars');」です。記事の修正をしないと...

日本語のマニュアルがまだだけど

興味ある人は使ってみてね!語学力がある人は翻訳のお手伝いをしてみてはいかがでしょうか!

2010年11月24日水曜日

PMBOK(1) - デスマーチと残念な仕事の作り方

PMBOKに出会うきっかけに良いスライドがありましたので紹介です。

とにかくやってしまおうが全て

奇跡的に良い仕事ができたケースを除いて、最初のヒアリングとゴールの設定がうまくできていないプロジェクトはうまくいかないことが多いと思います。お客さんから依頼されてやる仕事も、社内のプロジェクトとも基本は同じで、知識や経験不足はともかく変な期待(甘え)と無謀な自己過大評価が重なり合うと残念な仕事になります。そしてさらにデスマーチまでに仕上げるには、無理なスケジュール&作業量というスパイスが必要です。実はカレーを作るくらい簡単にデスマーチは作れちゃうかもしれないと最近思うようになりました(笑

しかしそれじゃいかんのだ!!

1日でデスマーチという単語を複数人から聞いて...

なんだよ、これから新しいこと始めたいって時に縁起でもないこと言うなよ!と思いつつ、プログラマーの日常に潜みきれずに露呈されてるデスマーチ。デスマーチというか超過勤務&ストレスの高い仕事ですが、ダメとは言え、一時的なものであれば仕方がないと言えます。が、慢性的になると問題です。まずそんな悪い環境に本当に優秀な人材は入ってこないし、稀に優秀な人材が育っても、よほど情に脆い人でない限りは他所へ行くでしょう。深夜になっても会社の明かりが消えない、休日でも出社している人がいる会社は、従業員がクレイジーなほどにやる気に満ちあふれてるのは置いといて(冷めた時が衰退時)、人の入れ替わりが早いとなると、良い評価はされません。Web業界は3年会社に居たら長い方かもしれないという人材の流動が激しい業界ではありますが。

PMBOKふたたび

CSS Nite in HIROSHIMA, Vol.3で、Webプロジェクトマネジメント標準 PMBOK(R)でワンランク上のWebディレクションを目指すの著者の林千晶さんのスライドがいいですね!プロジェクトを成功させたいのなら、PMを目指すのなら、PMBOKに学び実践しましょう!僕はPMは目指してませんw でも、Webの仕事はどれもプロジェクトとして捉えることができるので、PMBOKで得た知識を少しずつ生かしてます。まだまだ勉強中です!

この本はWebサイト制作に特化したPMBOK(ピンボック)系の本です。Webサイト制作とはいっても全般ではなく、Webアプリなどソフトウェア的な部分は詳しくは触れていません。しかし、Webをやってる会社は1冊置いておいて損はないです。置いておくというよりか、実践しましょう!

9つの知識エリアの中でベスト4はこいつらだ

  1. スケジュール(タイム)
  2. 品質
  3. コスト
  4. 作業内容(スコープ)

まず、スケジュール、品質、コストの中の優先順位が大事です。作業内容はその3つの関係によって調整します。忘れてはいけない項目なのであえてあげました。

とにかくいいものができたらいいからは落とし穴

コストとスケジュールが不明で、いいものができたらいいからという言葉には、すでに煙が立っていることがありますw 後から「いつごろできそう?」と聞かれ、スケジュールも気にし始めるし、そもそも使えるお金は限られているんですから。

林さんのスライドを紹介したくて書き始めてしまったこの記事ですが、せっかくですので、次回に上にあげた4つの関係性についてもう少し詳しくまとめてみたいと思います。

2010年11月7日日曜日

CSS Nite in MIYAZAKI, Vol.1をやりましてん

台風で二度目の延期かと思ったけど、無事開催できました

ほんと、天も味方につけてやった感じでした。いろいろとあったけど、周りの人に支えられなんとか丸く納めることができましたー!ありがとうござましたm(_ _)m

セッションの内容も良かったし、120名くらいの真剣な眼差し、メモを取る人を見てると実行員としてやってよかったーと思いました。特に50名が参加した親睦会で同業者が賑やかに話をしてるのを見た時は言い表せない喜びを感じました。

本当は5月開催で今頃が2回目の開催の予定だったけど、口蹄疫により開催直前に延期になったりといろいろありました。今回も台風のせいで危うかった。今回開催できてほんとによかった。またやりたいですね!!

写真はくろ。さんのブログにあります。すごく綺麗です。

2010年10月7日木曜日

ツールには拘ろうぜ!!GitXとP4Merge MacでGit GUI化計画?

P4Mergeを使ってみた

後述するGitXのフォークを入れた関係もあってgit diff|gitxができなくなったぽく、なにかdiffビューワ的なものないかなーと探していたら、いいの見つけました!Eclipseに入ってるやつみたいな感じです。ただ、なぜか一つ一つファイルを開いて行くのが難点で、1つのウィンドウに収める方法がないか探してます。あと最初の起動が重いです。重いけど、入れるだけの価値はあるかも? XCodeについてるFileMergeより全然使える。でもgit diffする度に起動されるのはつらいので、オプション的に使った方がいいですね。

GitXのフォークがいい!

Brotherbardさんのフォークがいいです。githubにおいてあります。ブランチ、リモート、タグが左側に出るし、GUIから操作できる項目が増えてます。GitX使って(る|た)人ならとりあえずスクリーンショットを見てみてよさそうなら入れてみるといいと思う!

2010年8月29日日曜日

プログラムを短く書く〜其ノ参〜 class属性を活用する

class属性によるグループ化

今回はHTMLとJavaScriptとCSSの話になりますが、前回のコードはID属性を使用して要素を特定していましたが、要素を個別に指定する必要がなくグループ化できる場合はclass属性を使用します。
function switchDateSelectForm(){
  var disabled = this.checked && this.value == 0;
  $('#start-year').attr('disabled', disabled);
  $('#start-month').attr('disabled', disabled);
  $('#start-day').attr('disabled', disabled);
  $('#end-year').attr('disabled', disabled);
  $('#end-month').attr('disabled', disabled);
  $('#end-day').attr('disabled', disabled);
}
$('input[name="enable_selecting_date"]')
  .change(switchDateSelectForm)
  .filter(':checked')
  .change();
これが、こう。
function switchDateSelectForm(){
  var disabled = this.checked && this.value == 0;
  $('.select_date').attr('disabled', disabled);
}
$('input[name="enable_selecting_date"]')
  .change(switchDateSelectForm)
  .filter(':checked')
  .change();

select_dateというクラスに操作対象の要素を入れ、select_dateに所属する要素に対してdisabled属性の変更を行っています。

セレクタに委譲と単一責任の原則

短いコードを書く話ではなくなりますが、classを使うことで、switchDateSelectFormがどの要素に対して操作するかをある意味委譲させることができます。classはCSSのセレクタでも使用することがありますが、今回のselect_dateはスタイルを設定するためのセレクタとしては使わず、オブジェクト指向の単一責任の原則のように、どうしてもその必要がなければこのclassは日付けの選択の有効無効の操作の対象にするだけに留めておいた方が良いです。select_dateクラスにイベントがバインドされることで、後から時刻のフォームが追加になった場合も、classにselect_dateを持たせることで、HTMLの変更だけで済むようになるメリットもあります。

クラスを使わず、構造に依存するセレクタの罠

$('.select_date').attr('disabled', disabled);
// ↓ 文脈セレクタ化 個人的には非推奨
$('div.select_date > select').attr('disabled', disabled);

セレクタはグローバルに働くため、文脈セレクタで対象を狭めることがよくあります。上記くらいの文脈セレクタならそれほど問題ないかもいれませんが、「#contents #contact-form div.select_date select」くらいまで長くなると、HTMLの構造に大きく依存し、HTMLが変更されるとJavaScriptもCSSも変更する必要が出てくる可能性があります。これは変更が発生することが考えられる案件では間違った設計と言えます。コードのメンテナンス性を上げるためには、classを有効活用した方が良いでしょう。しかしその場合はclass名の重複を避ける必要が出てきます。ネーミングについてはまた別の機会に書けたらと思います。個人的にもまとめたいのでw

知らない人も意外といるので書いておきますが、classはホワイトスペースで区切ることで複数設定可能です。数に制限はありませんが、煩雑になりやすいので注意が必要です。

2010年8月27日金曜日

プログラムを短く書く〜其ノ弐〜 if elseを見直す

if elseで無駄なコードをたくさん書ける罠

例えばラジオボタンでHTMLフォームの有効・無効を操作するJavaScriptが次のようなものだとします。

function switchDateSelectForm(){
  if(this.checked && this.value == 0){
    $('#start-year').attr('disabled', true);
    $('#start-month').attr('disabled', true);
    $('#start-day').attr('disabled', true);
    $('#end-year').attr('disabled', true);
    $('#end-month').attr('disabled', true);
    $('#end-day').attr('disabled', true);
  }else{
    $('#start-year').attr('disabled', false);
    $('#start-month').attr('disabled', false);
    $('#start-day').attr('disabled', false);
    $('#end-year').attr('disabled', false);
    $('#end-month').attr('disabled', false);
    $('#end-day').attr('disabled', false);
  }
}
$('input[name="enable_selecting_date"]')
  .change(switchDateSelectForm)
  .filter(':checked')
  .change();

無駄です。こう書けます。

function switchDateSelectForm(){
  var disabled = this.checked && this.value == 0;
  /* もしくは
  var disabled;
  if(this.checked && this.value == 0) {
     disabled = true;
   }else{
     disabled = false;
   }  
  */
  $('#start-year').attr('disabled', disabled);
  $('#start-month').attr('disabled', disabled);
  $('#start-day').attr('disabled', disabled);
  $('#end-year').attr('disabled', disabled);
  $('#end-month').attr('disabled', disabled);
  $('#end-day').attr('disabled', disabled);
}
$('input[name="enable_selecting_date"]')
  .change(switchDateSelectForm)
  .filter(':checked')
  .change();

条件分岐の外に出せるものは外に出そう

if elseでは以外とやりがちな事です。コツは条件分岐の外に出せるものは外に出す!これだけです。今回の例も簡単ですが、あまりこういったことを教えている初心者向けの入門本に書いてない気がしたので、取り上げてみました。

2010年7月20日火曜日

プログラムを短く書く〜其ノ壱〜 ifを使わずにboolを代入

JavaScriptでselectedとかcheckedを操作する時とか

// よくある書き方
if(this.value == 'value') {
   this.selected = true;
}else{
   this.selected = false;
}

// 短い書き方
this.selected = (this.value == 'value');

jQuery.eachなんかで使えます。使えないケースは代入したくない時。もともと==演算子はboolを返す言語がほとんどだと思うので、どの言語でも使えます。4行程読んで処理内容が分かるより、1行で分かる方が良いと個人的に思うので、よくやります。その言語特有のもので分かりづらいものなどは避けますが、意外と「これって無駄じゃね?」ってコードを書いちゃうので、なるべく短くそして分かり易いコードになるよう日々努力中!!

2010年6月23日水曜日

Fixtureのフォーマットって何がええのん

YAMLでもarrayでもない何か... CSV?

職場で、テスト用データを準備してちゃんと情報の漏洩とかしないかテストしないといけないとなって、まずはコードレベルで保障すべくユニットテストをするとなったわけだけど、CakePHPのFixtureのコードを見せて、これ書きたいですか?って聞いたら、「んー」という返答。やっぱりね!という感じです。確かに、EclipseやTextMateとかじゃ補完しにくい部分。テンプレートやスニペットを用意すればいいんだけど、コードが縦に長くなる。それで結局CSVでいくことになるわけだけど、CSVは横に長くなる。でも文字コードの問題を無視すればExcelとかでGUI的な編集もできる。でもでもでもでも、結局何がいいんだろ?

とりあえずDB設計上の問題から実行する順番をファイル名でルール付けして、CSVからINSERTしまくるようにはした。これでユニットテストとか、実際で操作してテストするためのテストデータの流し込みはできるようになった。Railsとかのmigrateじゃないけど、DBスキーマも一発で最新版に同期できるようにしてるので、これでしばらくは持ちこたえられそう。時間があったらYzwのサブパッケージ?に入れようと思います。

2010年6月16日水曜日

TextMateで行の最後にセミコロンを入れるコマンド

Control + ;でカレント行末にセミコロンを!

JavaScript、Scala、Rubyはそうでもないのですが、文末にセミコロンがいる言語は多い。そういった言語のほとんどが行末にセミコロンを書く事が多い。で、行末に行くにはTextMateだとControl+Eでいける、vimだとShift+$。それでカーソルを移動させてセミコロンを挿入するのもいいが、本来の目的は行末にセミコロンがない場合セミコロンを入れること。TextMateではデフォルトでCommand+Enterで行の途中でもその下に新しい行を追加しカーソルを新しい行の先頭に持ってきてくれる。わざわざControl+EしてEnterしなくてもいい。それに発想を得て、作ったのが以下のコード。

インストールの仕方

  1. ~/Library/Application Support/TextMate/Bundles/PHP/Commandsに移動するかディレクトリを作成して移動
  2. このgistを「Insert semicolon end of line.tmCommand」として保存

使い方

  • PHPファイルを開くか作成し、何かセミコロンで終わらない文を入力して「Control + ;」

2010年6月14日月曜日

wordpressでクリックしたカテゴリの小カテゴリだけ表示する方法

以下のようにCSSを変更or追加すれば実現できます

たぶんね!

.children { padding: 0; display:none; }
li.current-cat ul.children { display:block !important; }
li.current-cat-parent ul.children { display:block !important; }

カテゴリのリンクをクリックすると、そのカテゴリのli要素のcurrent-catがclass属性に付くようです。その上階層のリスト(親カテゴリ) にはcurrent-catがつくようなので、それを利用して、子カテゴリを一旦全部非表示にして、current-cat-parentが付いているカテゴリの下の小カテゴリを表示するように書いたつもりのCSSが上のものです。 読み込まれているCSS(たぶんstyle.css)に、適切に書き込んで下さいw

2010年6月7日月曜日

if __name__ == '__main__'をRuby PHP Python Perlで

直接実行された時とincludeされた時で挙動を変える

この方法を知っていると、再利用性を意識したプログラムを書く習慣を身につける為や、テストする時に役立つかもしれない!まずは言語の文化的によくやるPythonから

Python

if __name__ == '__main__':

Ruby

if __FILE__ == $0

Perl

if($0 eq __FILE__)

PHP

PHPはコマンドラインの場合、register_argc_argvが有効になっている必要があります。

// コマンドラインの場合
if (isset($argv[0]) && __FILE__ === realpath($argv[0]))

// Apacheモジュールの場合
if (basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])) 

インクルードされたら実行しないメリット

例えば関数やクラスの定義は普通にしておいて、そのテストを上記のプログラムの条件がtrueの時に行うようにできる。テストフレームワークを使わない時とか、日常よく行う処理を自動化して関数化した時のテストとか。同じviewを共有するけど、viewがindex.phpに直接書かれている場合に、ロジックだけ別にしときたい時とか(危険)。知ってて損のないものなので書いておきました。

2010年5月28日金曜日

PHP PostgreSQLであ行検索とか簡単にする方法

preg_replaceとSUBSTRINGとINと

$japanees_row = trim(preg_replace('/./u', "'$0',", 'あいうゔえお'), ',');
$where = " SUBSTRING(family_name_kana, 1, 1) IN({$japanese_row})";

こんな感じですね。注意点としては、他の行は濁音や半濁音があることくらいでしょうか

文字列を一文字ずつ配列にする方法 JavaScript PHP Ruby Perl Python Scala

いろいろやってみたなかったの

パスワード自動生成とか、とにかくランダムな文字列を生成する時に、substringみたなので何文字目を取得するという方法と、文字列を配列に落として配列のキーで取得する方法とありますが、今回は後者向けというか、各言語の違いをちょっと調べてみました

JavaScript

var strs = 'abcdefg'.split('');

Ruby

strs = 'abcdefg'.split('')
# split '' でも可能

Scala

var strs = "abcdefg" split ""
var strs = "あいうえお" split ""
# .を入れてもOK

PHP

$strs = str_split('abcefg');

Perl

@strs = split //, 'abcdefg';

use Encode;
@strs = split //, decode_utf8('あいうえお');

Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-

strs = list('abcdefg');
strs = list(u'あいうえお');

2010年5月21日金曜日

PHP SQLで同じフィールドに対してORを何回もやる時とかに使える方法

配列を駆使する(implode)

ちょっとgistが使えるかのテストも含めて

んー、ちょっと文字が小さいですが、直接ファイルを見れるからいいや!

これだと、すっきりしてるし、配列の最後の処理とかもないので、一度この方法を身につければずっとこのやり方になると思います。他にスマートなやり方があったら是非教えて下さい!

2010年5月14日金曜日

PHPでメタプログラミングの最初の一歩は__callから?

__callはRubyでいうMethod Missingかしら

PHPにはいくつかマジックメソッドがあって、そのうちの一つが__call。__get __setはYzwでほんのちょっぴり使いました。

__callって遅いらしい。でもさっき試した範囲では別に劇的に遅いとは感じなかったです。むしろ__callを使ってメタプログラミングしといて、スピードが求められる時にコードを書いてしまえばいいんじゃないかと思います。最適化ってやつです。

メタプログラミングの一歩手前?

最近モデル名とデータベースのテーブル名に規約をもたせててるのと、それぞれのテーブルからデータを取り出すクラスを親クラスから派生させて作っているので、findByIdを親クラスで定義して子クラスの名前からテーブルを割り出して該当するレコードを返すというメソッドを書きました。findById以外も書いたんですが、そのおかげで8つの子クラスからメソッドが消えて親クラスのメソッド1つに集約することができました。まだまだクラスが増えていく予定なので実装してよかったと思った部分なので、さらにメタプログラミングに磨きをかけて、コードを書く量を減らして効率化を計ろうと考え中!

でもあれですね。やっぱりPHP5.3がいい。PHP5.3ならActiveRecordとかORM系ライブラリがもっと充実してくるんじゃないかと思います。

2010年5月11日火曜日

CakePHPのPaginatorで0件表示を変えたい

$paginator->hasPage()で判定する

詳しい仕様はWebで!PaginatorHelper::hasPage()。CakePHPよくできてますね!

2010年4月13日火曜日

IEでセッションが使えない

ドメインが原因でし (アンダーバーは使っちゃだめ!)

[PHP-users 29064] Re: セッションが使えないので教えてください。

ローカルの開発環境で特にバーチャルドメイン使ってる場合だと、こういう現象が起きそうですね。というか起きました。SafariやFirefoxは大丈夫だったので、クライアントの問題だろうとセキュリティの設定を見たけど分からず、ググったら出てきました。確かに、昔使ってた開発環境ではアンダーバーは使わずにハイフンを使ってたなー。

2010年4月8日木曜日

Smarty3はget_template_vars()じゃなくてtpl_vars[key]->value

Smarty3のドキュメントはどこだ!

今日、ある部分の自動化を行っていて、SmartyとControllerとのフレームワークの連携のところのバグをなおしていたんですが、そのバグの原因がtpl_varsが返すのが配列じゃなくてオブジェクトだったということ!Smarty3からはオブジェクト指向を全面に出してるとはどこかで目にしたけど。まさかそこまでオブジェクトにするとは!という感じで、形見の狭い思いでせっせとバグ潰ししてました。get_class_methodsとかってオブジェクト渡したらget_classして自動でクラス名取得して対応しろよ!とか思いませんか?ぶつぶつ...

というか、Smarty3のドキュメントってどこにあるんだろう。正式なものでなくてもいいので、分かりやすいところに置いておいてほしいなー。今日初めてSmarty3の中身のコードを読みました。3秒くらい。こいつか!ってすぐ分かったので、綺麗なコードだと思います。でもドキュメントはほしい。Smarty2との互換性がない部分が多い。

Yzwを作ってるうちに...間違いがいろいろと...

Viewとの連携のところで、View側にすぐさま丸投げすればいいところを、フレームワーク側で一時的に面倒を見てる部分があるんですが、それは間違いだということに気がつきました。さっさとviewに渡してしまって、あとはお前で管理しろよ!ってところはそうした方がいい。他との連携の兼ね合いでフレームワークが仲介をするなら別だけど。こういう仕様の修正をしだせばやっぱり夏頃までは公開できないか...

ちなみに今日はDispatcher兼Router役の20〜30行ほどのクラスに、CakePHPのnamed parameterみたいな(URL中の/page:1/とか)のを取り入れました。あとはpaginatorもどきを作れば、一覧の並べ替えとかはDRYにできるなーとニンマリ企んでいます。

とりあえず、明日、というか今日を乗り切れば、テストフレームワークとの連携も真剣に考えないと。フレームワークにバグがあるだろうから、他の変更の副作用が予想外のところに出た時のために、テストを自動化しとかないと...

2010年4月6日火曜日

ワーカホリック

最近残業多いな

ワーカホリックかもしれない。これは褒め言葉じゃなくて、一種の病気というか麻痺状態。打ち込める趣味や、人との交友関係が薄い人がなりやすいんだけど、今の自分は案外そうかもしれない。あまり勤勉じゃないけど

たぶんワーカホリックといっても、二種類に分けられる気がするし、そのどちらも当てはまる場合があると思う。1つは、惰性で残業するタイプで、残業する俺エライと思ってそこで自尊心を守ろうとするタイプ。こういうのはスケジュール引きが下手。あ、僕の事ですw 2つめは我武者らタイプ。とにかく走り抜けろ的な感じで、自分の健康も顧みずガンガンやり、ある日プッツリ逝っちゃうか、入院するまでやる人。僕はこのタイプではないですw

でもワーカホリックってよくないですね。時間をかければ仕事をこなせるのは当たり前で、残業すれば体力と気力が持てば仕事も進むけど、そういうやり方してると日中に集中できてなかったり、合理化をしようとしない。

でもでもでもでも、僕みたいなタイプのワーカホリックの一番いけないところは、周りまで残業させる雰囲気を作り出してしまうこと。これはさっさと仕事を終わらせて帰りたいと思ってる人のやる気を削ぐし、残業してる人同士の不気味な連帯感を生む。昨日何時まで残業したって話を自慢しだせば末期に近い。期日前で優先度が非常に高いタスクのために残業するのは当然のことだけど、優先度順も付けずにとにかく期日優先でやる場合、エアコンとか電気代が嵩む上に、深夜手当まで付けないといけないから、僕が経営者だったら「帰れ!」と言うと思う。日頃は定められた時間内に仕事を終わらせるよう努めるべきで、多少の余力を余しておき、いざという時に残業してタスクをこなすというのがいいんだと思う。それにこの業界は日々の業務をこなしながら何でも習得できるほど浅くはないから、時間を作って独学で勉強していかないといけないし。なんとかせねば。

せっかく良さげな人が入ってきたのに、給料低いは残業多い(というか帰りにくい)はで辞められちゃったんじゃあ、こちらもダメージがでかいし、んじゃ僕も辞めちゃおうってなっちゃうだろうから、改善しないとね。

自分のスキルが全然だめだから仕方ないという原罪意識が残業を助長してるのもあるなー。でもそれだったら、家で勉強すればいい話だ。感情に流されないようにしなきゃ。

最近のYzw事情

コードを綺麗に整形するのと、テストコードを書くのをすれば公開してもいいレベルだとは思うのですが。0.2くらいのバージョンでw まだまだ作り込もうと思えば作り込めますね。最近はYzwのユーザスクリプト側を充実させることが多いので、あまりコアの方を手入れしてませんでしたが、URLに日本語を使えるようにしたり対応やビューとの連携の強化をしてました。RailsやCakePHPからも拝借してる部分があって、SinatraとCakePHPが混ざった感じになってます。既にある案件で使っているので、そろそろサイトを準備してドキュメント化を進めねば。

Yzw自体はすごくシンプルで一見使い道もなさそうなんだけど、 FooController < AppController < Yzwと継承をさせると、結構面白い事ができます。Yzwをシンプルに保つためにAppControllerにいろいろ書いたりしてるんですが、他のプロジェクトでも同じようなことをしないといけないのは無駄なので、ライブラリ化するかYzwに直接手を加えればいいと思ってはいるんですが。Yzwの拡張方法を便利で簡単にする方法も時間を作って探っていこうと思います。

最近、MVCのことをもう一回ちゃんと勉強し直そうと頑張っています。Yzwを作りながら、目的と役割をきちんと捉え、コードでそれを表現していくことに勤しんでいます。時間に追われてるとなかなかまともにやれないけど、コードが綺麗にかけた時はほんと嬉しい。あとはテストコード...w テストコードを書く事で、それぞれの仕事を細分化&単純化しメンテナンス性を上げ、ソフトウェアの信頼性を上げねば!

でも今一番やりたいのは、あの人のシルエットを切り抜いてYzwサイトで使う事!!(笑)

2010年3月30日火曜日

Redmineのガントチャートがネストする!

サブタスクをサポートしたらしいよ!

詳細はこちら。すごい!さっそくアップデートしよ〜♪。ちなみにアップデートしただけじゃだめで、設定のロールと権限で権限付与が必要。Redmine頑張ってますね!グローバルに置いてるサーバからはRedmineは外すけど、ローカルサーバには置いてるので今後も使って行きます。

2010年3月29日月曜日

CakePHPでデバッグ情報を消す裏技

HTMLを直接出す困ったちゃん

CakePHPのConfigure::read() > 1 (引数省略はdebugが渡されることになる)だと、DboSource::showLog()が強制的に実行されて、レンダーされたものの最後に必ずSQLの情報が付加される。それはそれで有り難いし、普段の開発ではその方が助かるんだけども、CSVファイルとかHTML以外のファイルを出力する時は邪魔でしかない。

一時的にdebugを0にすればOK

debugが1でも実行時間がHTMLのコメントアウトで付加されるので、HTML以外のファイルで、そういった文字列が勝手に出力されるのが不都合な場合は、レンダー直前でConfigure::write('debug', 0);とすればOK!裏技でもなんでもないけど。一つ注意なのは、デバッグ系で使うもの(pr関数とか)が使えなくなるということ。

ソースを読んでみたら、このデバッグ情報のところはdebugの数値によって強制的に出る。他に消す方法がないか(使用するレイアウトを変えるとか、レイアウトを使用しない(falseを渡す)とか)探ったけど、どうもだめっぽい。デバッグ情報は、必要ならその時表示して、あとは開発モードならログファイルに書き込んどくっていうくらいでいいと思うんだけど、CakePHPはその辺は男は黙ってログ出力!らしい。

controllerのlogメソッド経由でCakeLog::writeをするのは、開発時のデバッグ情報よりも、稼働中に起きた是正すべきエラーのログを残すために使った方が良いと思うので、目的が違う。 showLogメソッドを改造しようかと思ったけど、今回はConfigure::write('debug', 0)をタイミング良く呼び出すことで対処した。でもこれって、RSSとかXML、バイナリデータをもっと扱うようになると面倒というか、この仕様じゃ普段の開発と違うしで、なんか変だなー。ハードコーディングはBKよ!

2010年3月28日日曜日

ペットロス

久々に技術系じゃない内容

実家で飼っている犬(ミニチュアダックスフント 12歳)が病気になり、先日手術して昨日退院した。まだ手術後間もないので、あまり元気はない。歳も歳だし、昼間から寝てるのが普通なんだけど、食べ物への執着だけはすごく、何か食べ物の匂いや袋から物出す音を聞いたがしただけで目を覚ましたり、くれ!と暴れ出すんだけど、ここのところそれもない。腹部の毛を剃られているので、お腹が冷えないように毛布をかけてあげているが、普段なら遊びと勘違いして毛布を噛み散らすんだけど、それもない。術後だからそんなもんだろうと思って、あまり普段と変わらず接しているつもりだけど、やっぱり傷跡を舐めないかとか、痛がってないがと気にはなる。それに年齢的にも別れはそう遠くないという意識がさらに強くなってしまった。見た目はいつも子犬みたいなのに。

やれるだけのことをやる

家には物心ついた時から犬がいて、なぜか犬の面倒は自分が見るということが多かったんだけど。中学高校と成長するに家に帰る時間も遅くなり、あまり散歩とかしなくなった。そんな時、小学生の頃から飼っていた犬が病気で突然死んだ。忠誠心が強い犬で賢く、家族には吠えないし、お客さんが来ても最初吠える程度で長くは吠えない。外で鎖に繋いで飼っていたけど、トイレの場所も決めていて、犬にしては臭くなかった。ほとんど洗ってあげたことがなかったけどw あまり面倒をみてやんなくても、とにかく尻尾をふりふりして、頭を低くして、耳も寝かせて甘えてくるかわいい犬だった。病気になったのは突然で、病気になった次の日の夜には死んでしまった。最後を看取ることはできなかったけど、死体を庭に埋めるのには立ち会えた。

その後、一人になる時間まで耐えた。家で一人になった時、仏壇の前で泣いた。哀しいという感情よりも、全然世話しなかったことを悔やむ気持ちばかりで、謝りながら泣いたのを今でも覚えている。

その時からペットの世話はちゃんと見ようと思った。これはその死んだ犬が教えてくれたことだと思うし、自分の中でも罪滅ぼしでもあると思う。無理なことはなかなか続けるのが難しいけど、できることはできるだけやると決めた、死ぬその時まで。

死を免れることはできないし、普通に考えて飼う時から順番的に死ぬのは犬の方が早いのも分かっている。衰えてゆく姿を見ながらも最後の時までしっかり面倒を見てあげたい。もうあの時と同じ後悔はしたくないから。

2010年3月26日金曜日

PHPでcamelizeとunderscore


ちゃちゃっと!eval(preg_matchのcallback)は使わず関数の組み合わせで。5.3使いたい><

// アンダースコアをキャメルケース
function camelize($str) { return str_replace(' ','',ucwords(str_replace('_',' ',$str)));}
// キャメルケースをアンダースコアに
// 5.3以前
function underscore($str) {return strtolower(preg_replace('/(?!^)[A-Z]/', '_$0', $str));}
// 5.3
function underscore($str) {return strtolower(preg_replace('/[A-Z]/', '_$0', lcfirst($str)));}

//実行結果
camelize('aiue_eo'); // AiuEo
underscore(camelize('aiue_eo')); //aiu_eo

2010年3月17日水曜日

PHP6の先行きが怪しい

FUD?

PHP6開発 UTF-16化を断念、5.3へロールバック

えー!でもUTF-16化しなくなくなったのはいい事だと思います。これからどうなるんだろ。とにかくPHPは使い捨て言語って割り切った方がいいのかな。。。もったいないなー

2010年3月15日月曜日

CakePHPで生SQL

ナマ言ってんじゃないよ、と

実はCakePHPのModel->queryでも「?」の置き換えができたりと、意外と便利。でもPDOを使ってる身からすると:keyword形式の方がやりやすい。あとエスケープの仕方はSanitize->escapeでいいのかな?? なんかその辺の情報の薄さが微妙...。調べるよりもやり方知ってるから自力でエスケープしたくなりますね><

個人的には AS Model__fieldはよく使います。その方がテーブルから取得したデータの配列構造がCakePHPらしさを失わずに済むので。

JOINしたくなったよ〜

CakePHPのModelは便利君だけど、ある期間の集計とか、前年比とかになると、たぶん直接SQLを書いた方が早い。実行速度も全然その方が気がする。でもどうなんだろ、CakePHPマスターからすれば、そんなのちゃんとアソシエーション組んどけばできるよ!って言うのかもしれない。LEFT JOIN table_a as prevous_year ON table_a.year = (table_a.year - 1)みたいなのって、アソシエーションの指定でいけなくもなさそうだなぁとは思います。でもSUM(CASE WHEN table_a.day <= 10 THEN table_a.price ELSE 0 END) AS price_10 みたいなのを書き出すと、ちょっとソースが汚くなりそうだから、いっそのこと$this->queryっちゃいたくなるんですよね。

2010年3月10日水曜日

Smarty3でエスケープをデフォルトにする方法

Smarty2では$default_modifiers でもバグがあった模様

//smarty側
$this->default_modifiers = array('escape:"htmlall");

//テンプレート側
{$escaped} //エスケープされる
{$unescaped|smarty:nodefaults} //エスケープされない

どういったバグがあるかについては、Smartyのバグ ~default_modifiers~が参考になります。再帰処理はSmarty2でdefault_modifiersを使いたくなったら書こうかな。でも基本的にスカラの時だけエスケープすればいいと思うので、配列の時は何もしないってのがいいと思います。

Smarty3ではvariableFilter(関数名)

マニュアル読んでないし(まだ出てない?)、ソースも全然読んでないのでひょっとしたら公式なやり方じゃないかもしれない....けど、これで動きます。

//Smarty側
$this->register->variableFilter('escape');
//フィルター関数
function escape($string, $smarty){
  return is_string($string) ? htmlentities($string, ENT_QUOTES,  SMARTY_RESOURCE_CHAR_SET) : $string;
}

//テンプレート側
{$escaped} //エスケープされます
{$unescaped nofilter} //エスケープされません

ちなみにSmarty3.0b8で試しました。バグはどこかに残ってるはずだけど、Smarty2より2〜5倍速いようです。ほぼ完成してるらしいので、早く安定版出してほしいな〜!

ちゃんとやるなら? loadFilter('variable', 関数名);で定義してる関数を読み込んで、variableFilter(関数名)とするのがいいのかもしれません。

PHP5.2以前で静的遅延束縛もどき

PHP5.3から使える静的遅延束縛

静的遅延束縛は、簡単にざっくりと説明すると、__CLASS__を呼び出す時に、定義してるのクラスの名前が出るところが、static::__CLASS__書けば、継承してるクラスの名前を取れる感じです。が、ちゃんと理解したい人はググって下さい。この理解の仕方で留まるのは良くないと思うのでw(無責任)

static::__CLASS__はget_class($this)でも代用できる、問題は__METHOD__

結論から言うと、できません。もしやり方が分かってる方がいらっしゃれば教えて下さい(T_T)。当たり前じゃんと思うかもしれませんが、__FUNCTION__もだめでしたw 呼び出し元を特定できるといいんですが、PHP callerとかでぐぐったらデバッグ情報から取り出すってのは見つけたけど、なんかそれはちょっと...

URLDispatcherが規約に基づいてるので、そっちの方で$this->setCurrentMethod('メソッド名');で設定する感じでやりました。何がしたかったかと言うと、クラス&メソッド名からviewファイルのパスを得る処理です。静的遅延束縛が使えればstr_replace('::', '/', strtolower(static::__METHOD))で実装して、命名規約を作っちゃえば済む話になります。便利!

何言ってるか全然分からないという方は、いずれ公開されるであろうYZWのソースをお読み下さい。

PHP5.3は何気にいい

PHP5.3なんてPHP6への踏み台で微妙なバージョンでしょ〜なんてナメてました。でも違いますね。使いたい機能がある。名前空間、?:、静的遅延束縛などなど...

5.3をどんどん使って行きたい。

2010年3月8日月曜日

PHP extractは$thisを上書きするように一瞬見える

$thisに直接代入するとエラーがおきる

Fatal error: Cannot re-assign $this

$this = 'aaa';なんてすると、致命的エラーが出ます。たぶん$thisにあたるものがある言語で、$thisを変更するのは自殺行為的。

extract関数だとエラーが起きずに上書きされるように見える

class PollutionTest{
  // $thisが上書きできちゃうかテスト
  // $thisは上書きされたらだめなんだけど...
  function polluteThis(){
    var_dump($this);
    $this->method();
    extract(array('this' => 'This has been polluted!!'));
    var_dump($this);
    $this->method();
    echo $this;
  }
  
  function method(){
    echo 'Method Called', PHP_EOL;
  }
}

$obj = new PollutionTest;
$obj->polluteThis();

//実行結果
object(PollutionTest)#1 (0) {
}
Method Called
string(24) "This has been polluted!!"
Method Called

$thisは文字列になったはずなのに、メソッド呼び出しができるという謎。実際は上書きはされない。おそらく文字列を入れた時は$thisという文字列を入れた変数が別に存在している(呼び出し方は不明)。その関係で?__toStringメソッドが呼び出されなくなる模様。実際上書きはされないけど、なんらかの影響があるのはまずいですね...

外部からのデータは直接extractしちゃだめ

戒律ですね。viewを呼び出すところでこんな風に書いてる場合もあると思うので、注意が必要です。

class View{
  public function render($locals) {
    unset($locals['this']);
    extract($locals);
    include($this->template_file);
  }
}

Skype Off

なんだかつながったりつながらなかったり?

Skypeのオンライン状況って若干リアルタイムじゃないですよね。というよりも、最近どうもオンラインになったりオフラインになったりする日があるようで、コンタクトリスト上の人たちからうざがられます>< 知らんがな!と言いたいけど、あれ?急にメッセージ来なくなったとか、届かなくなったとかなったり、音声チャットが切れたり、最初はプロバイダの仕様とも思ってたけど、どうも違うっぽい。

オンラインになっても、自分がオンラインになったのがすぐ伝わるユーザとそうじゃないユーザ、自分側から見てもまた然りで、「リストから外した?」とか言われる始末です。

なんだか疲れたので、音声チャットで会話する日以外はあまりつけんとこ。気が向いたら再インストールしよう...

My skype seems have some problems so that I don't log on skype untill I reinstall it successfully. But I'll do when I need to do Skype-to-Skype call. Email me when you need to contact me. And also whenever you want to! :)

2010年2月24日水曜日

Rails 3.0 beta をインストールしてみた

gemいろいろ

sudo gem install tzinfo builder memcache-client \
     rack rack-test rack-mount erubis mail \
     text-format thor bundler i18n
sudo gem install rack-mount -v=0.4.0
sudo gem install rails --pre
sudo gem cleanup bundler

bundlerの古いバージョンが入っているとcleanupしろという警告が出ます。

ブログ作ってみる

途中だけど、1.8.7と1.9.1では動きました

rails blog
cd blog
bundle install
rails g scaffold article title:string body:text #2ではscript/generateだった
rake db:migrate
rails s #2ではscript/serverだった

動きました。てか、1.9系を使ったというのもあってか、速くなってるって分かります。まだbetaなので今すぐ何かに使おうとは思いませんが、安定板がリリースされたらプラグインの対応状況を見つつ、Rails3やってみようかなと思います。ローカルではどんどん開発していきたいけど、仕事でも使うと考えるとまだ2.3系をしっかりマスターしとかないといけない。

2010年2月23日火曜日

オフショア〜!

賃金が日本一安いと噂の県で働いています

なんだか、東京に比べて人件費が安いからということで、東京で仕事とってこっちで開発ってことを考えてる(実際やってる)人?会社?がありますが。全然勝てる気感がねーなーと思ってたんです。なんでかなと思ってたら分かりました。オフショア開発ですね。案の定、東京進出に失敗してる会社がちらほらとありますね。たぶん技術や経験値を見てもオフショアできるところの方がこっちの名の知れてない会社よりかは全然上でしょうね。安易に人件費を低くしたってデフレしかおきねーよ!賃金上げて><(切実) これは僕の言葉じゃありません(笑)

まー給料安いといい人材は集まらないし、いい人材に育ってもどこかに流れちゃうでしょう。

どうなんですか、オフショア

自分が経営者で英語、中国語が堪能だったらオフショアやっちゃうかも。でも、エンジニアだから、ウォーターフォールみたいな感じで下請けとか孫請けとかなってるとつまらないと思うだろうし、そういう面は日本より明らかにドライな人たちが多いだろうから、ある程度アジャイルの要素も入れないと人材流動がすごそうだ。

オフショアよりグローバルなSOHOがいいんじゃね

僕はデザインが苦手というか、よくツールの使い方も分からないし、あまりセンスもないので、デザインは外注にしたいなーとか、ロゴデザインとか他人に任せたいと思うんです。で、そこで対日本人よりも、よその国の方がおそらく今は安くで働いてくれるんだろうから、SOHOのもっとグローバル化してしまえば、個人や集団とがそれぞれやり取りして仕事しちゃうんじゃないかと思ってます。企業はでかいことをやりつつ、個人事業や5人に満たない企業で回るんじゃないかと。お給料はPayPalで払いますみたいな感じだと税関系とかどうなんだろ?

危機感を持ちつつ抜け道を探す

テクノロジーのいいところか悪いところか知らないけど、プログラマーって基本的に何かを効率化させるわけで、その効率化によってそれまでそれを仕事としていた人たちの職を奪う仕事をしてるわけですが。だからといってプログラマーは永遠かというと、日本の工場が中国に移ったように、プログラマーの仕事も分業化されて日本SIerが要件定義や設計をして、インドや中国に開発を発注するという感じになる流れは普通なんだと思います。アメリカもインドに支えられてるし。

今は日本で特に専門の資格も持たずにプログラマーの職業につけたり起業できます。オフショアのせいでそれがすぐに厳しくなるとは思わないのですが、今までよりは厳しい現状に立たされるんだろうとは思います。それよりも深刻なのは既に受託開発を収入源にしてる起業でかつ大半が日本人というところ。たぶん日本人よりインドや中国の方がハングリー精神は旺盛だろうし、過酷な競争をサバイバルしてきた人たちがたくさんらしい(インドは1000万人のSEがいる)。しかも専門の教育を受けているとあれば、大抵の日本人プログラマはかなわないのかなー。どうなんでしょう。僕は勝てる気配はなさそうですが、でも大学とか出てる人とか中学生や高校生の頃からプログラミング三昧な人たちはいけるだろう!と思います。でも、きっとそういう人たちが日本には不足してるんでしょうね。むしろあっちがそういう人たちばかりなのかな。

ん、これはまとめられない気配... 仕事って、一つは依頼主ができないことを代りにやってその手間賃をいただくってのがあると思います。だとすれば、コストがそれなりに納得のいく範囲であれば、オフショアのデメリットよりも、身近でなんとなく信頼の置ける人に依頼するんじゃないかと思います。とはいっても、安くて安心ならそっちに金が動いちゃいますね〜。

ん〜、やはりこれからは個人の時代だなー。あれーまとめられない。個人というか、仕事を作れる人間が仕事をする時代が来てるんじゃないかと思う。大学出ないとまともに就職できないって、不況が理由なんじゃなくて、効率化が招いた部分もあるんじゃないかな。パソコンのスペックが良くなるほど、それを使う人がこなす仕事が増えるって言うから、自分がこなす仕事が増えた分他人から仕事を奪ってるとか奪われてると考えてみたら分かる。これからのPGやSEやPMは営業やプロデュース能力がないと厳しいってことですね!おわり!

2010年2月19日金曜日

Gitでバージョン管理してCakePHPを使う SVNも同様

開発環境に依存するファイルはバージョン管理に含んではならぬ!

いきなり余談でごめんなさい。この記事の一つ前の記事が釣りなんですが、ちょっとアクセスが多くて焦りましたw

本題ですが、例えばtmpフォルダ内のキャッシュなどの一時的なファイル(ログとかも)、config内の開発環境に依存するもの(開発環境によって設定を変えるもの)はバージョン管理に含みません。変更して間違ってコミットしたら、他の人の環境にも反映されて動かなくなっちゃうっていうトラブルが発生するからです。

無視して別名ファイルを用意する

キャッシュ系は別名ファイルは要りません。Gitの場合は空ディレクトリはバージョン管理の対象にできないので、emptyとかいうてきとうな名前の空ファイルを置けばいいです。.gitignoreで管理するのがいいと思います。

設定ファイルは別名ファイルを用意しておきます。例えばdatabase.phpをdatabase.php.sampleにしておいて、実際に開発する時にdatabase.phpというファイルにコピーして使います。database.phpは.gitignoreでバージョン管理対象外として指定されていることが前提です。core.phpもお忘れなく!

OS依存のものはグローバルに無視するようにする

Thumbs.dbとか.DS_Storeなどは、バージョン管理に含めないのはもちろんですが、各リポジトリの.gitignoreに書くよりも、各ユーザの.gitignoreに書いておく方が良いと思います。とは言っても、Thumbs.dbをコミットしそうな人がいる場合は、早めにリポジトリの.gitignoreに書いてコミットして先手を打っておいた方がいいかもしれませんねw

いい感じの.gitignoreが出来たら晒します

近々自分でもCakePHPを使う案件用に.gitignoreを用意しとこうと思うので、それが出来たらgistで晒します。この記事にも貼付けようと思います。あ、誰かが先にやってたら、そこにリンクを張ろう♪

2010年2月17日水曜日

GitとCakePHPとRedmineでスーパーアジャイルな開発!!

釣りです

今職場実習生が来てるので、CakePHPで社内ツールのプロトタイプを作成してもらってます。

実習生の実力はというと、VB.NETとC#をやっていたということでオブジェクト指向OK!でも3年間のブランクありという僕より10歳くらい上の淑やかな女性です。

なぜいきなりGit?CakePHP?Redmine?

理由は至ってシンプルです。実習が終わった後に実習生が「何をしたかが言葉以外の情報でも見えるようにしたかったから」。どういうコードを書いたのかを知っておかないと、社内ツールとして採用された場合にメンテナンスをどうするかっていうことを考えれば、期間が短くてもやっておいて損はないと思います。そんなのやってる時間がねーよ!って会社ほどやるべきですね。でないとノウハウが貯まらない会社になってしまって、人が辞めるとそこでいろんなことが終わっちゃいますから。

RedmineとGitを採用しているのは会社に既に導入しているのと、Gitの方は導入実験も兼ねてですが、ブランチ開発をしてもらって、変更が追いやすい良質なコミットをしてもらうことと、一部CI的な要素も含んでます。CIについてはまだやらないので、良いコミットの仕方について何度か説明することになると思います。

CakePHPを採用した理由は、構造が分かっていればコードを追いやすいことと、CakePHPのルールに従って書いていれば、独特なコードがあまり生まれないということからです。社内ツールとして採用されれば、社内の人間がメンテナンスする日がくると思いますし、おそらく機能追加は必須です。そういった場合に、まずどういった作りになってるか調べて...という作業をせず、規約に沿っていることを前提に進める方が効率がいいと思います。また実習生に自社の独自のフレームワークについて教える場合は資料が必要ですが、CakePHPの場合はググって下さいと言えばOKです。ですが、ググっても分かりませんでしたと言われた時に、その問題を解決する手段を提示できることは大事です。

実はA4のしかも文字が羅列されてるだけのプロジェクトの概要と、目的、背景、目標と機能一覧みたいなものを描いた紙しか渡してません。口頭での説明もしましたが、自分で設計して実装して下さいと伝えました。なので実装の仕方は自由ですから、CakePHPを使うということを半強制的におしつけましたw

手書きの設計書からいきなりbake!

This is agile. とにかく動くものに仕上げてレビューをして、目的に合った使いやすいものにどんどん仕上げていくというポリシーで、画面設計に必要な項目を出してもらい、あとシステム上必要な項目を洗い出せば、画面設計とDB設計は完成です。もし詳しいドキュメントが欲しいとなれば、開発が終わった後にまとめる感じです。

アジャイルって設計書とかのドキュメント書かないんじゃないの?と思う人もいるかもしれませんが、そうではなく、最初にどういったもの作るかという使う側と作る側のコンセンサスを得るのは大事です。途中で大きな変更があってもプロジェクトが快活に進むなんてどんな開発手法であれほぼありえません。スコープをある程度明確にしておくことはアジャイルでも大事だと思います。

手書きが個人的に好きなのには理由があります。変更しやすいのと、誰でも鉛筆さえ持てば書き込めるからです。鳥頭なので会議の内容なんてすぐに忘れるので、紙に重要な点だけ書いておくというのは大事です。画面項目とその配置とかって、実際に絵にしてイメージを共有した方が早いし、資料として残るので後で整理しやすいです。画面を書いて、画面遷移も書きたくなってとなれば、手書きの方が絶対早い。お客さんも参加しやすいはずです。見やすいようにまとめるという作業はとにかく後回しにして、要点だけを抑えて、すぐに実装できるように持って行くことが大事だと思います。要求分析や業務分析や要件定義もこの中で全部やってしまって気づいたことはメモしときます。

必要な項目が分かって、項目の型も分かればテーブルを作って必要に応じてbakeします。もしくは、まだ項目に自信がもてない場合は自動のscaffoldを使って、使う側に項目の確認を実際に使ってみてもらって判断してもらえばいいかと思います。OKが出ればbakeして仕上げの作業に入ります。動くもののレビューをしては開発を進めるというイテレーションの繰り返しですね。社内の人間とは基本的に業務時間内であればいつでもコミュニケーションが取れるので、社内での開発はアジャイルが向いていると思います。

何かを達成して実習を終えてほしい

実は教わる側より教える側の方が学ぶ事が多いと思います。そして今回は社内ツール開発なので外目には触れません。じゃあ実習生は損ばかりかというと、経験が積めるからいいじゃないか!という話になると思うのですが、じゃあその経験の質をどうするかと考えると、本人が無意識に定めている以上の限界をこちらで設けて、それを達成できるよう持って行くのがいいんじゃないかと思っています。上から目線の生意気なクソガキが!とこれ見たら思われるかもしれないけどw

もう二日目にして、チケット駆動開発、DVCS、フレームワーク、ユニットテストと、その方が知らなかったワードがいっぱい出てきています。本人が大丈夫かなー?という心配に少しかられている様子です。教える側としても「順序組が下手でごめんなさい」とか思いますが、いずれ出てきたワードがいずれ芽吹いていくんじゃないかと思います。開発を進めるにあたって、どれも実際にやっていくので、その中のどれかがその方の未来で役に立つものがあれば嬉しいです。

成長できた気がします!とか本人が自覚している上でそう言われる、これに勝る喜びはないです。

my issues

うまく達成してもらうためには、教える側が指導の仕方を時間の合間をぬって工夫していかなきゃいけないところですが、今のところ全敗な気がするので、ちゃんとうまく説明できる人間になろうと思います。これをやってくれ、あれをやってくれは時間をかければある程度は説明ができるんですが、指示以外の部分でどう動くかという、動きが見えない部分の洞察力も必要だなーと感じます。将来部下を持った時に、その洞察力がないと、報連相がうまくいかない時に、それが開発効率のボトルネックになるのは防がないといけないと思うので。迷いは開発を鈍らせるので、迷いが発生する時にどうするかを見てみたいなとも。迷ったら聞きにきてという指示はもちろんありだと思うし言いますが、言ったからといって毎回そういう行動は取らないし、相手の事を考えて忙しいから聞くのを後にしようとか思うものだと思うので、何かうまいやり方というのがないのかなーと思います。100%は無理だし過干渉は良くないので、あれ?(妙に変だなー 某ラジオ番組出典)とすぐに気づけるぐらいになりたいです。上司の仕事の一つは、自分がいなくても仕事がまわるようにするだと思うので、latent observer パターン的上司を目指します!(笑)

2010年2月16日火曜日

PHPでDependency Injection Container

依存注入

英語だけど、DIとは何かとDIコンテナをどう実装するかについて分かりやすくまとめてるサイトを発見!!てかSymfony関連サイト?Dependency Injection Reinventing how you manage PHP classes

セッションDI

セッションの場合は、PHPのビルドインセッションモジュールか、DB使うか、memcachedを使うか(レンサバは厳しい)と方法があるので、インタフェースで各クラス間のメソッドと振る舞いを共通化するようにしといて、簡単に乗り換えができるようにするというのは極自然に理解できますね。でも必要に迫られない限りはやらなくてもいい部類です。GoFのデザパタには入ってないと思うけど、広い意味でのデザインパターン(MVCなども含む)って必要に迫られない限りはやらない方が賢明だと思います。

別件で

依存注入は普通にやるし、こういうのやりだしたらインターフェースとか抽象クラス使ったりとなりますが、ログを取るクラスの場合ってどう実装すればいいんだろ。グループウェアの活動履歴みたいなのを、クラス単位で取りたい場合って、それぞれのクラスにログクラスのインスタンスを注入すんのかな?? PHPだとそれが限界でしょうか。もう少し調べてみよう。できれば、各クラスはログのことを全く意識しないでいいような作りにしたいし。継承もせずに。というか単一継承なので途中でLoggableみたいな継承を入れると、それ以降のサブクラスも全部影響受けるから避けたいです。

2010年2月13日土曜日

アジャイルって契約どうすんの?

釣られちゃおう

アジャイルって受託開発との相性が最悪な気がする。んー受託というか、大規模開発には向かないのかもしれない、と薄々感じてます。

薄々というのは、まだアジャイル開発を実際に仕事でやったことがないからで実際なんとも言えないんだけど...

アジャイルは客を選ぶ

どういうものが欲しいかがある程度明確なお客さんじゃないと厳しいという意見を聞いた事があります。で、実際そうだと思います。というのも、要件やそもそもの目的を認識してないお客さん相手だと、ゴールを定めにくいから、アジャイルでやろうとしても、変更が激しくでどんでん返しもあり得そうで、怖いんじゃないかと思います。

イテレーションを繰り返す中でお客さんにレビューをしてもらって、じゃあそれを完成させるのに、あと一日かかりますと言うとして、それが契約日外に達する場合、まー通常だと1人日3〜5万として、あと3万下さいって言うようなもんで、チキンな僕にはそういうこと言えるのか??とか、もっと優秀なプログラマーなら2時間で終わるんじゃないか??とかいう自信のなさもあって、言えないんじゃないかと思ってしまいます。個人事業主でやってたら一日2万くらいが限度でしょう。だって税金収めるってなったら1人日2万以上はないと、いつ職に溢れるか分からないし

契約と開発人数?

今いる会社だと、開発を外注にまるなげするようなことはせずに自前でやっちゃうという態勢の方が絶対いいと感じるんですが、でも人数がきつきつなので、ドキュメントドリブンじゃちょっと割に合わないというのは感じます。

作成するもののうち成果物として先方に収めるものが出ると思うのですが、そのうち何を収めなければならないかは、契約で決まってくると思います。例えば受託開発でも製品の著作権が先方にあれば結構綿密な設計書を先方に成果物として収めるのが筋だろうし、逆に著作権がこちらの場合、収めなくてもいいとは思うけど、そういう場合は運用や保守はこちらでやるというケースがあるので、運用手順書やらは自社ないでちゃんと作成しとく必要はあると思います。人に依存させると会社としてのノウハウが貯まらないから。

Railsの本のイテレーション開発のサンプルを見てると、とりあえず契約なんかの話は置いといて、お客さんと先に概要の打ち合わせをして、だいたいやる事が決まって、画面遷移なんかを手書きで書いてイメージを共有してから、イテレーション開発に入るという感じです。

これはフリーでやってる人はそれで問題ないかもしれないけど、会社の場合は、開発に入る前の契約と、後のドキュメント生成のところが気になるはずです。Rubyの場合は僕はYardでドキュメント(JavaDocみたいなの)は作ってしまって、あとは運用マニュアルとかは、製品が出来た後から作るか、お客さんと一緒に開発してるんだし、お客さんの方で作ってもらうというのもありだと思います。問題はそのプロジェクトのスコープと役割分担であって、どっちが何をするかをはっきり決めておけば、アジャイルでも別に問題はないんじゃないかという点です。

個人的なアジャイルのイメージはウォーターフォールをV字型にして、内部設計からユニットテストから統合テストあたりをグルグル回すというのがあります。その外枠の要件定義や外部設計、それの対象にあたる成果物の承認なんかは、アジャイル開発の外でやって、うまくいったら終わり、まだ開発が必要なら再度契約という感じになるんじゃないかなーと思います。そこでお客さんが納得できるかどうかは分からないから、客を選ぶとか、プロジェクトの性格に依存するんだろうなと思いますが、設計書なしに何十人ものプログラマーを動かすってそうとう難しいと思うので、少人数態勢で開発にあたれないなら、アジャイルは不向きなのかもしれません。でも、どっちみち社内での開発の一部のプロセスをアジャイル化はできると思います。納品物に含まれる設計書のうち、誰も必要としないような細かい設計書を作っても意味がないので、そんなの作るより、動くものを作ってしまおうと考えるのは普通のような気がします。

やっぱり中庸!バランス感覚!

契約がうまく取れれば、半ウォーターフォール半アジャイルで進めるのがいいのかなと思います。どんな開発手法にしろ、いいものをできるだけ速く最良の品質で顧客満足度を満たし費用対効果を最大限に得られるものが、理想の目的であると思うので、それを達成するためにはどうするかを毎度考えることになると思います。「これ!」という答えがない分野でしょうしね。

開発メンバーも選ばれるかも

アジャイルは客を選ぶというけれど、開発メンバーもそれなりに腕のあるプログラマーじゃないと勤まらない気が薄々してます。だって変更を受け入れるというのもあるし、お客さんが言う要件を分析して実装するという要素もあるし、ということはそれなりの知識経験、そしてそれをひっくるめたセンス(テイスト)が問われるということですよね... 個人プレーならいいけど、組織のためにノウハウを残すとかなると... うー、頑張ります><

2010年2月10日水曜日

ホンモノになりたい

Professional

プロでもないくせにプロを語る輩が多い。

仕事でする以上はプロだ!という精神論でしか言わない人も同様に多いと思いますが。本物になりたい。Web系エンジニアの本物って何かというと結構いろいろあって難しいですね。

探究心

プロになる条件はいろいろあると思います。費用対効果、プロジェクト管理、プロジェクト管理の中でもリスク管理、契約管理、スコープ...その他もろもろができること。でも最終的に大事なのは目的(目標)をできるだけ短期間で達成すること。そのためには何をするか、それが一番大事。その要をきちっとやれるのがプロなんだなと思います。

仕様書にしろ設計書にしろ、システム構成図、グランドデザイン、納品物といろいろ作るものは多いかもしれないけど、結局それは何を達成したいがためで誰のためで何を解決するかというのが根本にあるんだと思います。根本を解決するための逆算こそが仕事に求められている気がします。

悔しいけれどアマグラマーな自分

プログラマーの中にアマグラマー(かアマグラマーに毛が生えた程度の人)が蔓延っていると思います。悔しいけれど自分もその一人だと自覚せざるを得ません。SEとPGを分けるのが日本流っぽいですが、関係ありません。仕事としていただいた以上はちゃんとやり遂げないと。そのためにはレンタルサーバありきとか、レンタルサーバに毛が生えた程度のシステム構成でプログラマーなんて名乗れませんね>< マスタースレーブだの、データキャッシュ、メンキャッシュ、ハッシュDB、ロードバランサー、ルータによるセグメント分け、ファイヤウォール、ウイルスチェックといろいろ考慮することがあります。

要件の分析、要件から推測されるシステムの構成の費用別パターンの割り出し、システム構成に依存したアプリ設計などなど。やること覚えること山積みというのが分かってきました。

そしてプログラムの著作権や瑕疵担保責任などなど契約管理とか。そういうのをほぼ一通り知って経験して本物になれるんだなと思います。

レンタルサーバに毛が生えた程度で終わってもいい場合もあると思います。それでも僕はそれが自分のできることの範囲にと決めず、ちゃんとお客様の要望を効率よく実現できるエンジニアになりたいなと思った今日この頃でした。もっといろんなことをちゃんと知って自分をスケールアウトしたい。

久々に今日は独り言というラベルをつけたいけど、ラベルなしで行こう。あ、メモで。

追記: コメントありがとうございます

こういう同業者にも、そうでない人にも煙たがられそうな、嫌われそうな記事にコメントしてもらえると、向き合ってもらえている感じがして、とてもありがたいです。お金をもらった時点でプロというのも、そういう捉え方もありだと思っています。というかそうでないといけないんだなという感じです。じゃあ、それをプロしたなら、この記事で書いているプロってなんなのか?となると、要するにプロの中でも一流かどうかなのかだと思います。表現の違いにせよ、プロの中でも一流な人や一流を目指している人にはプロを感じます。プロを哲学していて、それを体現しようとしてる人や一部を体現している人。僕はそういう人にプロというものを感じます。そして所詮三流止まりでも、プロを目指したいと思います。

2010年2月9日火曜日

フレームワークが作りたくなってきた

PHPでmixinができるって知らなかったの

というか知ろうともしてませんでした。危ない傾向ですね。プログラマーとしてプログラミング言語を知りたがろうとしないのはかなり危険な状態だと思います。いかんいかん...

きっかけはCakePHP

CakePHPは機能が豊富で助かります。豊富な分、ソースを追えません。僕の力量では無理です。気力的に。

でも大事なことを学びました。PHPイケてんじゃん(※但しイケ鯖に限る)。

ActsasはRailsにもあるけど、CakePHPで見てみて、「へーこんなことできるんだ!どうやってやるだろう?」と久々にPHPに興味が湧きました。あとCakePHPをやるにつれ不明な点が出てきて他人に訊く前にソースリーディングをしてみたのですが、それがいろいろ勉強になりました。やっぱり他人様のソースを読むというのは大事ですね。面白いです。(辛いけど)

ルーティングと構造とMixinとJavaScriptの軽いラッパー的なものがあればそれでいい

フレームワークにいろいろ求めるときりがないですが、CakePHPはよくできてる分、違うアプローチには対応しにくいように思えます。効率的なところは効率的!でも、それをやるためにあるソースが多すぎてちょっと困る。

フレームワークって、結局は「自作したい」ってなるものかなと思います。あれもいい、これもいい、でもあれが足りない、これが足りない、あれが違う、これが違うで、模索するうちに、理想の形が見えてきて自分で作ってみようかなと。そして泥沼にハマって...(ネガティブ)

しかし、なんとなく自分が求めてるものが分かってきました。とくにPHPでは、SQLは直書きでも問題がないケースばかりだし、その方が速いし、逆にバリデーションをモデルから分離してmixinさせたいし、JavaScriptと連動させたい。万人向けでなくても、そういうコアだけどありがちな用途で使える貧乏フレームワークを作ってみたいなーと。dispatcherでルーティングとディレクトリ構造とを決めて、あとは必要なところは規約か設定ファイルに依存させてしまえばいいのかなと思います。

作るかどうか分からないけど、作るならPHP5.3以上でやろうと思います。作らなくても、CakePHPから学んだ事をどんどん活かして行きたいと思います。コードジェネレータ的なものは欲しいよね。HTTPサーバもPHPでできると最高なんだけど... まー、まずはPHPでmixinからです!

2010年2月8日月曜日

JavaScriptでプライベート変数

コツはthisを書かないこと

隠蔽というかカプセル化もオブジェクト指向の醍醐味の一つだと思っていますが、JavaScriptでは言語がプライベート変数のようなものはサポートしていません。ですが、クロージャをうまく使えばできるのです!

var f = function(){
  var _private_var = '';
  return {
    getter:function(){ return _private_var; },
    setter: function(string){ _private_var = String(string); return this; }  
  };
};

return this;が好みです

上記の例ではシンプルにゲッターとセッターだけ実装してます。セッターの場合は何もreturnしなくてもいいんですが、return thisをしとけばメソッドチェーン(カスケード?)ができるので好きです。表現力が増しますし、複数の処理を一つにまとめてしまうことを回避できる場合があります。

Rails3がベータリリース

期待感が高まってきました!

公式ブログに「Rails 3.0: Beta release」という記事があがっています。インストールの仕方も載っています。

個人的にRailsで遊んでいて、merbに手を出してから少し経った後に、この(当時)Rubyの二大フレームワークが統合されるというアナウンスが出ました。それから約一年経った頃から、矢吹田猫(wycats)さんがいろいろブログに書き始めました。Rails3とSinatraを同時に使う方法とか。

Rails3はパフォーマンスの改善、XSSの強化、フルスタックからモジューラ?に変わってます。ActiveRecordからActiveModelにバリデーションが分離されたのもかなりいいと思っています。prototypeからjQueryにデフォルトが変ったのか、それともjQueryに簡単に置き換えられるようになったかRailsの最新版を落として試したけど確認できてませんが、jQueryのことが気になりますw

コマンド周りも変わっていて、script/serverだったのがrails serverになるなど、さらにシンプルで分かりやすくなっていますね!残念なことにドキュメント生成ツールにyardがまだ採用されていませんが、いずれはされるんじゃないかと思います。あとはPHP文化みたいにドキュメントを異常なほどに多国語でそろえてほしいなーw

Rails3はHTML5を使うことを想定してるみたいで、DOCTYPEがHTML5のものになってますね。で、JavaScriptで必要なDOM属性をdata-*を使ってのをDHHが言ってたけどどうなるのかな。個人的にはRailsに限らず、業務系アプリはHTML5を使ってdata属性を使おうかと思ってます。(IE対応だと厳しいのかも?)

Sinatra1.0もリリース間近

これも何気にすごい。RubyがDSLパターンに強いのを活かしたWeb用フレームワークで単純なウェブアプリはこれで作っちゃえばいいんじゃないかと思います。英語圏の方ではSinatra Bookを作ろうと頑張っていて、アプリを作りながら進めているようです。今年はRubyで面白いサイトを作ろう!!

2010年2月7日日曜日

SubversionからGitへ移行した理由とこれから

その前に、Macユーザ諸君!

GitのGUIで何かいいのないかなーと探しているあなたに、GitXをおすすめします。ログの閲覧だけかと思いきや、ステージとコミット、ブランチ切りががGUI上でできます。コマンドからの呼び出しもできるので、CUIとGUIの両方の架け橋を綺麗な画面でやってくれる便利君です。GitはGUIがないからなーとか、gitkの画面に絶望したあなたにおすすめです。何ができるかまとめようと思ったんですが、公式サイトに書いてあるので(See it参照 Screencasts=動画もあります)見てみて下さい。ソフトの方はOSSなので、時間を見つけて日本語化の作業をしてpull requestしてみたいと思います。

Windowsユーザの方はTortoiseGitがいいんじゃないでしょうか。

Subversion否定派ではありません

推進派でもないけれど、最初に断っておかないと。SVNは現在も使ってますし、フックスクリプトを書いたり、コマンドを組み合わせて遊んだりしてるので、それなりに使っている方だと思います。中央管理型なので、分散管理型よりも使いどころがあるところはあります。

理由1) リポジトリの作成と複製が簡単

Subversionはまず個人向けではないという気がしています。リポジトリを作るのにadminという他のコマンド系が存在し、リポジトリはチェックアウトして作業用ディレクトリを作らないと使えません。そしてチェックアウトした方の全ディレクトリに.svnというディレクトリが作られます。これはディレクトリをそのままコピーした時に副作用を起こすので扱いに注意が必要です。.svnのアクセス制限を忘れてapache上からリポジトリの中身を見れるという事態も招きます。一方GitやMercruial(以下hg)、Bazaar(以下bzr)は.git .hg .bzrというディレクトリをトップにだけ置くので管理体制がシンプルです。リポジトリの作成は作成したいディレクトリでinitするくらいです。このサクサクやれるのが個人的に好きです。

無責任な話ですが、分散管理の場合、最悪リポジトリサーバがお亡くなりになられても、チームがcloneしているリポジトリから復旧できます。無責任な話と言え、ぶっちゃけ!、社内サーバの管理は徹底してない会社がほとんどじゃないでしょうかw

理由2) ブランチ開発が簡単

SVNでブランチ開発をやったことがないのであれですが、そもそもあまりやろうと思う程にまで便利でないような気がしています。Gitの場合、ブランチを作るのが簡単で、ブランチ用にディレクトリを作る必要はありません。ブランチを切り替えればその状態にファイルを自動で入れ替えてくれます。

Gitでは基本的にmasterは統合ブランチです。統合ブランチの細かい説明は省きますが、要するにいつでもお客さんに見せていい状態であったり、最新版(ただし安定板とは別)という位置づけです。バグ修正や機能追加はトピックブランチを立てそちらで作業を行いテストにパスしたら統合ブランチにマージします。この流れが普通なので、Gitでは簡単にできるようになっています。ブランチで機能追加中に見つけてしまったバグの対応、割り込みの対応、そういったこともGitでは難なく対応できます。

バージョン管理の副作用

バージョン管理というよりも、チーム間でのソースコードの共有という点で問題になるケースがあります。リリースが何回かに分けてされるものは、リリース間近になるとある時点から後に追加される機能は取り込まずに(影響を受けたくないから)、バグ修正に徹底したい時期がくると思います。ここで新機能についてはコミットを中止させておくというのは避け、リリースブランチ(統合ブランチの一つ)を設け、masterブランチ(SVNではtrunk)に新機能、リリースブランチではリリースに特化した作業(バグ修正など)を行います。

SubversionでもGitでも共有するリポジトリにリリースブランチを作ることはしますが、Gitの場合はローカルにだけブランチを作ることが可能なので柔軟に対応できます。(hg、bzrも同様)

Gitに限らず気をつけておくこと

コミットはクリーンでクリアなものでなければなりません。バグ修正と機能の実装が同じコミットに入っていると、他の開発者がバグ修正だけほしい(pullまたはcherry-pickしたい)のに、必要ない機能まで取って来てしまいます。とりあえず何をやっただけ記録するものという運用のやり方では、チーム開発の場合だと限界がやってくると思います。Gitではコミットの前にステージというステップを踏むので、SVNほどシンプルではありませんが、逆にそれが良いコミットができるよう助けてくれます。Gitのコミットの仕方については別の機会に触れます。

SVNからGitへ移行しようと考えている方へ

SVNよりもGitは覚えなければならないことが多いです。SVNとは違い、分散管理は自分自身でリポジトリを管理する能力が必要になるからです。How-to的にまとめておくことが親切ですが、概念もしっかり覚えてもらわないとリポジトリが乱れます。ただし覚えてしまうと開発効率はグンと上がると思います。

それからリポジトリ管理を自分ですることに不安がある方は大丈夫です。やり方はありますが、基本的にgitはあなたがgitにさせたことを全て記録しています。これはコミットだけではなく、resetなどの取り消しも含まれます。間違って取り消してしまっても、実は復旧できるのです!最初のうちは救われますよw というか復旧の仕方をまず最初に知るべきです。これもまた別の機会に。

ちなみに、gitはgit-svnがあるので、gitを使いながら、svnリポジトリにアクセスすることができます。

これから

今年の案件のうち、カスタマイズ用リリースブランチを作る必要があるであろう案件があります。契約がまだ曖昧なのでどうなるか分からないのと、明確になるのかさえ定かでないので、手間ですがカスタマイズ用のリリースブランチ、もしくはリポジトリを作成して作って行く予定です。カスタマイズ用のリリースブランチにするかリポジトリにするか、または別の手段でいくか、いい方法が見つかり実績ができたら、そのことについてまとめたいと思います。

2010年2月4日木曜日

PHPで関数の引数の順番を忘れたら

しかもphp.netを開くのがめんどいというあなた!

php -hをご覧あれ

  --rf <name>      Show information about function <name>.
  --rc <name>      Show information about class <name>.
  --re <name>      Show information about extension <name>.
  --ri <name>      Show configuration for extension <name>.

そうです。php --rf (関数名)でターミナル上から確認できるんです。便利ですね!

PHP 妥当性チェックとかで楽がしたくて。。。

is_numeric & over zero

PHPではfalse null 0 '0'が==演算子だと同じなので、厳密にチェックしたい時は===を使いますが、数値の0と文字列の0は違うものとして扱われるので、データベースのint型で(特に1か0のフラグ系)、is_numeric関数と不等号で確認しますよね? それが何個もあるとif文が長くなるので、こういう関数を作っちゃいますw

is_numeric_over_zero(){
  foreach(func_get_args() as $v) { if(!is_numeric($v) || $v < 1){ return false; } }
  return true;
}
is_numeric_over_zero(1,2,3); # true
is_numeric_over_zero(0,1,2); # false

可変引数にしておくと便利で、ifの条件のところが長ったらしくなるのを防げます。もう少し短い名前の関数にした方がいいけどね!

return ( comparison );

三項演算を知ってるとそれ止まりというか、あまり見かけないのでやる人が少ないからあえて書いてみます。

//引数1が0以上であればtrue そうでない場合はfalseを返す関数の例
//三項演算の場合
function is_over_zero($numeric) { return ($numeric > 0) ? true : false; }
//こう書ける
function is_over_zero($numeric){ return ($numeric > 0); }
//郵便番号の例
function is_jp_zipcode($zipcode) { return (preg_match('/^\d{3}-\d{4}$/', $zipcode) > 0); }

比較演算子が返す値を知ってれば思いつくやり方です。僕はタイピングは遅い方じゃないと思いますが、なるべくコードを書かずして同等かそれ以上の成果を得られるよう心がけています。そしてコードが簡潔で意図を明確に表現するように頑張ってます><。Program Intently and Expressively(PIEの原則)とKeep It Simple, Stupid(KISSの原則)です。

2010年2月3日水曜日

PHPの配列でちょっと楽がしたくって。。。

集計とかする時にNOTICEエラーが

+=演算子を使う時に、あらかじめ用意されてないキーを指定するとNOTICEエラーが出るんですよね。NOTICEレベルだからいいとは言っても目障りだし、header関数の邪魔をするし、NOTICEレベルのエラーも回避せよ!なんて命令された日には大変ですよね。なので。。。

$array = ('a' => 0,'b' => 0,'c' => 0,....);
//こういう一々丁寧に書くのはやめてこう書く
$keys = explode(',', 'a,b,c,d,e,f,g....');
//5.2以前
foreach($keys as $key){ $array[$key] = 0;}
//5.2以降
$array = array_key_fill($keys, 0);

こうすると、やたら長いキーや、キーが多い時、追加したい時が非常に楽なのでおすすめです。嫌う人もいそうだけど。

5.2.0以降はarray_fill_keys関数があるんですね。便利!

Redmineの上手な使い方2(あえて最適化しない)

Redmineを合わせるよりも、Redmineに合わせてみる

「え?普通逆じゃん!?」と思われる方もいると思いますが、ツールを最適化してしまうデメリットも当然存在します。例えば、Redmineを複数使っていた場合、統合する際にカスタマイズした部分を統合するのはきっと大変ですし、もともとRedmineはそういったケースまでは想定されていません。ロールやワークフローやステータスは増やせますが、増やす際に一度考えるべきです。(結構面倒ですしw)

Redmineよりも、まずは手順を疑ってかかる

社内のワークフローや手順というものは、目的があってそれを効率的に行うために定められてると思いますが、手順書を作成する際に現場の声が入っていなかったりして、結局は使えない手順書というのもありますし、そもそもの目的が曖昧なものもあります。Redmineを導入した最初の目的は何でしょうか? Redmineを使う事を想定された手順ですか?PDCAサイクルは回ってるでしょうか?そこで「はい!」と即答できない場合は立ち止まって考えるべきです。

私的に思うのは、Redmineは部署が複数存在する会社で使う場合はよく使いどころを考えるべきだと思います。おそらくウォーターフロー型で言えば、内部設計から統合テストくらいまで(開発部門内で使うこと)が関の山ではないでしょうか。あとは営業マンが顧客に出向く前に進捗を確認するくらいの使い方ができると思いますが、要求分析や要件定義のフェーズから使うことは、Redmineのチケットのステータスを見る限りでは想定されてないことが窺えます。

もう一つ、Redmine以外にも言えることですが、グループウェアは「慣れ」が肝心です。要するに、運用ルールや習慣でカバーしてしまうということです。使う側に合わせるのも大事ですが、使う側も時間と共に成長し変わります。どう変わるかは分からないというのが難点です。Redmineを使ってどんなタスクも管理というのは理想的に見えますが、Redmineが最初から何もせずに使える分野が本来の専門分野の筈と考え、適材適所でいくべきです。(小さい会社では顧客管理までできるかもしれませんね!)

最適化で失うもの

それは汎用性であったり、工夫することであったりします。最適化が工夫の一つでもありますが、本当に最適化してしまうことが合理的なのか、長期的に見てそうでない場合は、運用面での工夫をするのがいいでしょう。カチッと決めてしまわずに、弛みを持たせるのもコツです。Redmineと自社の使い方の中庸を得ておくことが大事です。

Redmineの得意分野を知っておく

前回の記事にコメントをいただいているので書いてみようと思います。Redmineはファイル共有として使える機能もありますが、ファイルの中身までは検索対象になりません。印刷系には弱いですし、Wikiをすべて印刷するのは大変です。その辺はプログラムを自作してしまえばいいですが時間がかかります。Web上での情報共有には向きますが、オフライン(印刷して紙媒体にするとか)への対応はあまり考慮されていません。すごく残念ですが、WikiはPDF化されません(T_T)。それを踏まえて、従来の書類ベースのところは、Redmineのファイル共有と活動履歴を使うか、切り離して、情報の通達(ニュースやフォーラム、またはチケット)手段として使うのが良いと思います。そこがRedmineの得意分野です。印刷物にするとか、見た目が求められるもの、WYSWYG的な操作感はRedmineは得意としません。ファイル名やコメントにどういった情報が載っているのかを分かりやすく端的に表現して、ファイルはExcelや画像など自社で良しとされているフォーマットで作成する方が合理的だと思います。仕様が決まるまでは文書の改訂がいろいろ発生すると思います。そういった時は、その文書の置き場を決めておいてそこでやるか、バージョン管理で別に情報共有して、成果物をRedmineに上げるという方法が合理的だと思います。Excelや従来のソフトが得意とすることや、その方が速いというものをRedmineに取り込む時は注意が必要です。

それでも我慢できなくなったら

プラグインを作っちゃいましょう。もしくはRedmineを使うのを諦めましょう。選択肢を増やし、合理的なものをその中から選びましょう!

Ruby 1.8.x 1.9.x を使い分けるRVM(Ruby Version Manager)

インストール簡単、設定簡単、笑っちゃうほど簡単!

ridiculously easyと書いてある通り、RVMいいですね。use 1.9.2ってコマンドだけで切り替えられます。使ってみたいと思います。ちょっとまとめる時間がないので、また後日この記事を更新します。

Mac版にバグ?それとも仕様?

Mac版だとrvm use >バージョン< しても、ログアウトか再起動するとシステムのものに戻ってしまうようです!

Redmineの上手な使い方(チケット・フォーラムの切り分け編)

運用ルールを作ることが大事

Redmineは高機能で自由度の高いプロジェクト管理系アプリです。そして、こう使え!という態度を取りません。なので運用ルールがないと煩雑になってしまうことがあります。

うちではこんな使い方をしてるとか、良いアイデアがあったらコメントをお願いしますm(_ _)m

何をするか、しているか、したか、を見える化するツール

Redmineでタスクやソースの管理を行えば活動履歴で見える化はできます。しかし、その中には過去になると見えなくなるものが含まれます

流動していいものと、してはいけないものを分ける

例えばチケット。チケットは終了すると通常のチケット一覧からは消えます。探せば見つけ出せますが、面倒です。こういった流動してしまうものの中に、仕様に関することや調査内容、添付ファイルを入れてしまうと、一緒に見えなくなってしまって、見落としや情報へのアクセシビリティが損なわれます。

仕様やドキュメントはWikiや文書に載せておくのがベターです。例外的にトップページの画像の入れ替えで画像をチケットに添付したりというのはいいと思います。でもそれが流れてしまっては困る場合は、ファイルにアップしてチケットにはそのリンクを載せた方がいいです。情報共有には時間軸も含まれるため、過去の自分から未来の自分へはまだいいとして、過去の誰から現在の自分へなど、人と時間とがクロスする場合に、そういった流動による見落としや情報の伝達が断絶されることは避けるべきです。

チケットを発行する前にフォーラムで話し合う

フォーラムも頻繁に使えば流動するものの一つですが、トピックは大抵その時大事なもので、流動してもかまわないものだし、検索すれば出てくるのでフォーラムが適任です。フォーラムの中で流れては困るものは、ファイル、文書、Wikiのどれかを併用すればいいと思います(調査結果をまとめたものなど)。やる事が決まらないうちは、フォーラムで話し合い、決まったらチケットに落とすというのが良いでしょう。そういう決めごとがあるフォーラムは最初の記事にToDoを書いて明確にしておけば尚良いと思います。

2010年2月2日火曜日

設計する時に気をつけておく事

今日ちょっと反省したのでメモメモ。

依存度

設計する時に気をつけなければならないもののうち、今日気がついたことを一言で言えば依存度。

簡単にまとめると、例えばHTML構造にそった文脈セレクタを使ったCSSは、HTML構造に非常に依存しているため、HTML側で少しでも構造が変われば(divが抜けたり入ったり)スタイルが適用されなくなる。

ほんとに簡単な例なので、ピンとこないかもしれないけど、もっと悪い例の場合、規約に依存させる設計には落とし穴がある。例外的に規約違反が起きたらたちまち使えなくなる。

なるべく疎結させておく

やっぱり大事なのは疎結!CSSの例であればIDかクラスを指定するくらいで、文脈セレクタは使わないのがベターだし、そのコーディング手法を身につけておくとパーツデザインができるようになる。サーバやPCのパフォーマンスチューニングが必要にならない限りは、多少重いコードになっても、依存度を下げるプログラムを書いておいた方が身のためだと思いました。

ちなみにうまく疎結させるには、それぞれの役割を明確にすることが必要です。ここが難しくて、えーい書いてしまえ!となって、気持ち悪いコードを書いてしまうんだけど、ここさえクリアできれば、それなりのプログラマーにはなれそうな気がする!

追記

この記事を投稿してブログを表示したら奇跡が起きました。しかも悪い方の。なんと!例に上げたCSSの通り、なぜかBloggerの各要素のクラスが若干変更されてます!(汗 前はdiv.entry-bodyだったのが、div.itemtextになってたりと。。。なので一時的にフォントサイズがきちんと指定されず読みにくくなっていたかもしれません。しかし、こればっかりは設計とかの問題じゃなく、仕方がないのレベルですね。ただこういう問題は同じ組織内では起きてほしくないし、個人のタスクでは絶対に避けたいところ><

2010年1月19日火曜日

疎結と委譲

連載をやるといいつつまだ全然下書きができてない

しかし、最近オブジェクト指向、アプリケーション設計を考えることが多くなってきたため、デザインパターンちょっとだけだけど触れといてよかったと感じています。ちょっとでも知っていることで、解決への糸口が見つかる。そんな感じです。

疎結させること

オブジェクト間の依存をなるべく減らすことは、オブジェクトが集中すべき業務に対してより集中できるようになることが多々あります。例えば、テレビのリモコンの中身まで気にして生活している場合は、それは疎結されていなくて、ただリモコンはボタンがあって電源を入れるのとチャンネルを変えるのがある程度くらいのインターフェースを知っていればOKというのは、リモコンとユーザとか疎結されていると考えます(自分は)

このインターフェースに対して働くというのが疎結させる方法の1つだと最近考えています。

委譲させること

委譲は「あとは任せた!」という表上は信頼というタテマエと、裏では「そんな仕事にゃ興味ねーんだよ!」という臭い物には蓋をする的な意味合いがあります(ぇ。先ほどのリモコンの場合、ボタンを押した後の処理(電気が流れて、赤外線が放射されてなどなど)は、ユーザからは隠蔽されていますし、ユーザはリモコンにそのことを何も気がつかずに委譲しています。そしてリモコンは赤外線を放射した後は、知らん顔で、あとのチャンネル変更などの処理はテレビ本体のチャンネル変更担当機関に任せちゃいます。これが委譲。

疎結と委譲で各機能の役割が明確になってくる

そうなると部品化(モジュールやプラグイン)が簡単にできるようになったり、テストしやすくなったりすると思います。ここ1年半ほど、一人でプログラムを組む事ばかりだったので、とにかく再利用性に気をつけてきましたが、やっとちゃんとした部品が作れるようになりそうな気配がしてきましたw というかそうしなければならない

マッシュアップの時代へ

話は飛躍しますが、これからはAPI(いろいろありますが)やライブラリやフレームワークをごりごり集めて何かを作り出す力が必要になるんじゃないかと思います。今まで個人ではこなせなかった作業がオープンソースやAPIのおかげで、どんどんできるようになってきています。そしてRails3のモジューラビリティ(話が飛び過ぎ)。スクラッチからすべて起こしてやっていくのが古いとは言いませんが、個人でやっていく場合、マッシュアップは要だと思います。生産性や効率という意味では、再利用可能なプログラムが裏切ることはそうないと思います。ただし再利用されないとか、汎用性が必要ない場合は最適化したコーディングも必要だと思います。いつも最終的にはバランス感覚ですね。

2010年1月15日金曜日

CakePHPの語形変化を使う

Inflectorを使いましょう

//○
$model_name = Inflector::classify($this->name);

//× 直接書くのはスマートじゃない
$model_name = 'User';
そもそも、CakePHPに限らず語形変化が規約によって定められているフレームワークはInflector(語形変化用クラス)を持っているので、それを使った方が絶対に良いです。CakePHPの場合はInflectorのドキュメントがあります。

2010年1月13日水曜日

Subversionで無視ファイルを設定する方法

svn propedit svn:ignore >ディレクトリパス<

svn propedit svn:ignore config --editor-cmd=vim
--editor-cmdはEDITORかSVN_EDITORが設定されていない場合に、どのエディタを使って設定するかを指定するためのものです。エディタで開いたら、database.ymlとか無視したいファイル名やパターンを入力して書き込んで終了!

Windowsの場合はThumbs.db、Macの場合は.DS_Storeなど、毎回コミット時に邪魔してくれるやつらをこれで無視できます。たぶんTortoiseSVNでも、EclipseのSubversiveやSubclipseでも簡単に設定できたはずだけど忘れました。もしできてなかったなら、たぶん毎回コミット時にコミットしないファイルのチェックをはずす作業中に発狂してるはずだし。。。

版管理に入れないコツ

例えばRailsならdatabase.ymlやlog/*.log、CakePHPならconfig/core.phpなどなど、実行環境によって設定が異なるものは外します。その代わりに、設定サンプルとして、database.yml.sampleや、config/dist-core.phpなど別名ファイルを用意しといて、それをコピー(ファイル名はconfig.phpにするなど)して簡単に設定できるようにしておくと良いです。さらにさらにFTPにまで言及すると、これらの設定ファイルは基本的に編集しないはずなので、間違って編集するのをさけるためにあえてパーミッションを644から444にします。おすすめです!

バージョン管理は異なる開発環境間のファイルの共有にもなります。共有すべきでない、ローカル(環境)に依存するところは、多少手間ですが、上記のように工夫することで、無用な競合やエラーを回避できます。あとは手順書があれば完璧ね!Wikiに書くでもいいわよ!(誰

2010年1月8日金曜日

CakePHPでテストする時にFixtureのデータを再利用してDRYにしよう

DRYはDon't repeat yourself。コードの重複を省くこと

CakePHPのbakeで生成されたテストは微妙というより、そのままでは使えない。とくに$expectedのところ。

function testUserFind() {
  $this->User->recursive = -1;
  $results = $this->User->find('first');
  $this->assertTrue(!empty($results));
//ここ!
  $expected = array('User' => array(
    'id'  => 1,
    'name'  => 'Lorem ipsum dolor sit amet',
    'created'  => 'Lorem ipsum dolor sit amet',
    'modified'  => 'Lorem ipsum dolor sit amet'));

  $this->assertEqual($results, $expected);
}

// こうしたい
function testUserFind() {
  $this->User->recursive = -1;
  $results = $this->User->find('first');
  $this->assertTrue(!empty($results));
  $this->assertEqual($results, $this->UserFixture->records[0]);
}

この$expectedで定義している配列はFixtureでも定義しているんだし、そもそもFixtureで入れたデータをもとに検証するのだから、ここではそのままFixtureを利用すれば良いだけの話のはずなんだけど。。。

App::importでFixtureを呼び出す

やり方は簡単です。

//user.test.php)
// ..省略
App::import('Fixture', 'User');

class UserTestCase extends CakeTestCase {
//..省略
  function startTest(){
  //..省略
    $this->UserFixture =&  ClassRegistry::init('UserFixture');
  //
}
これで上記の「こうしたい」コードで動くようになります。

さらにコードの品質を上げる

コードの読みやすさも大事ですが、分かりやすさも大事です。そしてPHP配列の場合順番が変わる可能性がある(やり方次第だけど)のと、文字列を使って意味を明確するために連想配列を使うことをおすすめします。それと、Fixtureの$records以外はデータベースに挿入されないので、save時のテストデータや不正なデータなどはプロパティを分けて用意します。こんな感じ。。。

//user_fixture.php
class UserFixture extends CakeTestFixture{
  var $records = array('admin' => array(
    'id' => 1,
    'name' => 'Admin',
    'flag_admin' => 1,
    'created' => '2010-01-08 05:19:23',
    'updated' => '2010-01-08 05:24:52'
  ));

  // 不正なデータはIDを400〜499にするとかルール漬けして下さい!
  // 500台はインジェクションコードを埋め込んだデータとかね!
  var $invalids = array('name' => array(
    'id' => 400,
    'name' => null,
    'flag_admin' => 1,
    'created' => '2010-01-08 05:19:23',
    'updated' => '2010-01-08 05:24:52'
  ));
}

// user.test.php
//Fixtureの利用の仕方は上記参照
//名前が空の不正なデータの場合のテスト(バリデーション設定済みという設定)
class UserTestCase extends CakeTestCase{
  function testSaveInvalidNameUser(){
    $this->User->create();
    $this->User->set($this->UserFixture->invalids['name']);
    $this->assertFalse($this->User->save());
  }
}

残念なことに、このサンプルコード自体はテストしてないので動くか分かりませんが、雰囲気はつかめると思います。Fixtureを修正した時にテストコードの$expectedを修正する作業が減ります。メンテナンス性が向上しますね。

※ empty関数のところが!emptyemptyになってるのはコードハイライターのバグです

PHPがテンプレート言語っぽいのになぜそれでもテンプレートエンジンを使うのか

それが合理的だからです

もし合理的でない場合は使う必要がないだけです。

例えばエスケープ

生のPHPはHTMLのエスケープ処理がされない

$name = '<script>';
echo $name; #=> <script>
//CakePHPの場合
echo h($name); #=> &lt;script&gt;

//Twig (デフォルトでエスケープするよう設定できる)
{{name}}
//Smarty
{$name|escape}
このサンプルだけだとあまりメリットを感じないかもしれないけど、大抵の場合エスケープはしないといけないし、他にもnumber_formatなど整形する関数やヘルパなどを使うと思います。そのときに関数をe(h(g(d(f($name))))なんて書いて括弧の数が合わずにエラーを出したりするより、{$name|truncate|escape}と書いた方が読みやすい。

デフォルトでエスケープするのが主流になりそう

今知ってる範囲ではRails3では(2.3でも設定で可)デフォルトがエスケープ処理になり、直接データを表示したい時はrawを使うようになりました。Smartyもそうなるんじゃないかなーと勝手に思ってます。Twigは最近知ったテンプレートエンジンですが、なかなか興味深いですね!趣味でWeb制作をする人も多い世の中なので、デフォルトでエスケープするようになる方がいいし、仕事でもその方が効率がいいです。インジェクション対策の一つですね。

理由もなくSmartyを嫌うのはやめて

一時期Smartyが流行り、そして脱テンプレートエンジンが流行ったと認識してますが、どちらにもメリットデメリットがあると思います。問題はMVCのVのところで、テンプレートエンジンを使った方が、Vが行うべきタスクにより集中でき効率と品質が上がるかであって、そうでもないのなら使わなければいいだけの話です。PHP自体がテンプレート言語みたいなものだから、と思い込んで使わないというのは変です。

不変と可変の分離と抽象化と委譲と委譲と委譲の普遍性(1)

しまった、もう独り言というタグは消したんだった

このブログはどのラベルよりも「独り言」というラベルが貼られた記事数が一番大きかったのですが、ある日突然消えたんだった。

今回も独り言のようになりそうなのだけど、話がでかいので回を分けたり、ちゃんと図を作成して、自分が考えてることを整理するためにも記事を書こうと思います。

パターンに学ぶもの

デザインパターンを学びつつ、そして先日、プロジェクトの工程の話をしていた時にふと閃いたのが、不変な要素と可変な要素は抽出して分離したり、もしくはできるだけ疎結させて委譲できるようにした方がいいということです。いきなり抽象的な話かもしれませんが、考えること自体は簡単です。例えば、プロジェクトの場合、契約書は不変化されたものです。可変なものはヒトです。極端な話だけど。ヒトが途中で抜けてプロジェクトが出だしにもどるようなことがあるとすれば、そこは契約や書面でおさえておかなければならないし、それによってヒトに対する依存度を下げることができる。この考え方は、オブジェクト指向でも似てると思う。

なんじゃそりゃ!?ということを思われてそうだけど、それをうまく言葉化してここに載せれることができたら、それは自分の中でうまく整理できたことになるので、ちょっと頑張ってみたいと思います。ま、不定期ということで。

ラベルを何にしようか迷い中

2010年1月5日火曜日

CakePHP fixturesを使う際にbeforeSaveとかされない件

誰か良い解決方法知ってたら教えてください

ソースを見てみたら、モデルを経由せずに、普通にINSERT {$table}とかしてるからびっくらこいた。じゃあinsertする前に自力でやりたいことやらせていただく!という感じで解決。

サブクラスのinitで処理して親クラスのinitを呼び出す

(ソースを読み間違ってたらごめんなさいだけど、)残念なことにモデルを使ってsaveしないので、beforeSaveを使っても動かない。ので、再度beforeSaveでやっている手順を記述。あーDRYじゃないよ〜><。

// 独自の暗号化処理の例
class UserFixture extends CakeTestFixture {
 //...省略...
  function init(){
    foreach($this->records as $k => $v){
      $this->records[$k]['password'] = User::encrypt($this->records[$k]['password']);
    }
    parent::init();
  }
}