はてなブログ始めました
招待ありがとうございます!
symfony1.4でTwitter Bootstrap使ってたらデバッグツールバーの表示が残念になったのでなんとかした
小ネタ。
Twitter Bootstrapいいですよね。僕はバリバリ使ってます。
そんなBootstrapですがsymfony1.4でデバッグツールバーを表示させるときにちょっとだけ問題があります。
topbarクラスを指定してページ上部固定のトップバーを表示させていると、デバッグツールバーがトップバーの後ろに隠れてしまうんです。
なのでこの状態を解決するためにbootstrap.cssのあとから読み込ませるcssをすこしだけ編集します。
div.topbar { z-index: 1000 !important; }
symfonyのデバッグツールバーのz-indexが10000、Bootstrapのトップバーもz-indexが10000故に起きる問題でした。
アジャイルサムライ他流試合に参加しました
2011/09/18 に開催されました「アジャイルサムライ他流試合」に参加しました。
イベント概要
http://atnd.org/events/19733
@shinyaa31さんによる当日のつぶやきまとめ
http://togetter.com/li/189708
監訳者の西村直人さん(@nawoto)、角谷信太郎さん(@kakutani)、会場を提供していただいたオラクルの @yokatsukiさん、主催の@ShiroKappaさん、ust職人の@brtriverさん、ナイスな名札をデザインしていただいた@NEKOGETさん、会場の準備や受付などの運営を行ったスタッフのみなさん、そしてこの日のために集ったサムライのみなさん、全ての方に改めて感謝をいたします。
僕も当日スタッフとして会場の設営、案内など行なっておりました。
スタッフとして参加しておいてなんなのですが、とても楽しく参加することができたイベントでした。
楽しかった理由はあの会場に集まった全員が達人開発者への道をもがきつつも歩んでいる仲間だったから、だと思います。
仲間がいることを再確認できたことが僕にとっての最大の収穫です。
この経験を糧に、よりよい仕事をするように燃え上がっています。
ときには挫けそうになるかもしれませんがその時はあの他流試合を思い出して頑張ろう、そう心に誓いました。
師を仰ぎ、師を追いかけ、師に歩調を合わせ、師の意図を組み、そして自らが師となろう。
Ubuntuでもコードやテストを保存したら自動でPHPUnitを実行して通知する環境
@HIROCASTさんが書いた記事「コードやテストを保存したら自動でPHPUnitを実行しGrowlへ通知する環境」に感銘を受けました。
僕が使用しているUbuntuでも同じように通知する環境を用意します。
まずUbuntuでGrowlのように通知を表示してくれるnotify-sendをインストールします。
sudo apt-get install libnotify-bin
次にhttps://github.com/mynyml/watchrを参考にしつつwatchrをインストールします。
sudo gem install watchr sudo gem install rev
このままだとwatchrにパスが通っていないので、.bashrcなどにパスを追加するように設定しておきます。
PATH="/var/lib/gems/1.8/bin:$PATH"
設定した内容を反映させて、watchrが実行できるか確認します。
jiska@jiska-laptop:~$ source .bashrc jiska@jiska-laptop:~$ watchr -v watchr version: 0.7
OKですね。
あとは@HIROCASTさんが用意してくれた環境(https://github.com/hirocaster/phpunit-stack)を参考にしつつwatch.rbをUbuntu向けに変更します。
といっても変更内容はGrowlをnotify-sendに変えただけです。
変更したものは僕のgithubにおいてあります。
https://github.com/jiska/phpunit-stack
これでUbuntuでもテスト結果が通知されるようになりました。
よりよいTDDライフを。
2011.07.07 23:40追記
@HIROCASTさんの素早い対応でmac,Linux対応になっています。
PHPでTDD&CIワークショップにいってきました
PHPでTDD&CIワークショップにいってきました。スタッフのみなさん、会場を提供してくれたGREEのみなさんには感謝感謝です。
独学ながらTDDについて学んでるところなんですが、やっぱり同じ目的を持って勉強会に参加している方の手法や姿勢をみていると刺激になります。はじめてのペアプロも楽しかったです。jenkinsのセッションもすごく興味深いのであとでおさらいしてみたいですね。
さて、僕が参加したTDDセッションではおなじみのFizzBuzzをTDD手法で開発してみようというものでした。
とりあえずあの場で書きあがったコードを未完成ですが晒してみます。
<?php /** * Generated by PHPUnit on 2011-06-20 at 21:36:50. */ class fizzbuzz { function getFizzBuzz($i) { if (!is_numeric($i)) throw new Exception('数値以外はだめだよ'); if ($i % 3 === 0 && $i % 5 === 0) return 'FizzBuzz'; if ($i % 3 === 0) return 'Fizz'; if ($i % 5 === 0) return 'Buzz'; return (string) $i; } function getFizzBuzzList($from, $to = 1) { if (!is_numeric($from)) throw new Exception('数値以外はだめだよ'); if (!is_numeric($to)) throw new Exception('数値以外はだめだよ'); if ($from < $to) { $to = $from; $from = 1; } $result = array(); for ($i = $from; $i <= $to; $i ++) { $result[] = $this->getFizzBuzz($i); } return $result; } }
fizzbuzzTest.php
<?php require_once dirname(__FILE__) . '/fizzbuzz.php'; /** * Test class for fizzbuzz. * Generated by PHPUnit on 2011-06-20 at 21:39:26. */ class fizzbuzzTest extends PHPUnit_Framework_TestCase { /** * @var fizzbuzz */ protected $object; /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. */ protected function setUp() { $this->object = new fizzbuzz; } /** * Tears down the fixture, for example, closes a network connection. * This method is called after a test is executed. */ protected function tearDown() { } function test_getFizzBuzz_引数が1のときには1() { $this->assertEquals('1', $this->object->getFizzBuzz(1)); } // 別データでテストをすることで精度を高める function test_getFizzBuzz_引数が2のときには2() { $this->assertEquals('2', $this->object->getFizzBuzz(2)); } function test_getFizzBuzz_引数が3の倍数のときはFizz() { # Test関数の中のassertは1つがベスト $this->assertEquals('Fizz', $this->object->getFizzBuzz(3)); } function test_getFizzBuzz_引数が4のときには4() { $this->assertEquals('4', $this->object->getFizzBuzz(4)); } function test_getFizzBuzz_引数が5の倍数のときはBuzz() { $this->assertEquals('Buzz', $this->object->getFizzBuzz(5)); } function test_getFizzBuzz_引数が3の倍数かつ5の倍数のときはFizzBuzz() { $this->assertEquals('FizzBuzz', $this->object->getFizzBuzz(15)); } function test_getFizzBuzz_引数が数字以外のときにはException() { try { $this->object->getFizzBuzz('あ'); $this->fail('例外を返すつもりが反らなかったよ'); } catch (Exception $e) { $this->assertEquals('数値以外はだめだよ', $e->getMessage()); } } function test_getFizzBuzzList_引数が数字以外のときにはException() { try { $this->object->getFizzBuzzList('あ'); $this->fail('例外を返すつもりが反らなかったよ'); } catch (Exception $e) { $this->assertEquals('数値以外はだめだよ', $e->getMessage()); } } function test_getFizzBuzzList_1_to_16 () { $expected = array( 1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz', 16 ); $this->assertEquals($expected, $this->object->getFizzBuzzList(16)); } function test_getFizzBuzzList_2_to_16 () { $expected = array( 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz', 16 ); $this->assertEquals($expected, $this->object->getFizzBuzzList(2, 16)); } }
これgetFizzBuzzListを呼び出した際に第2引数がある時とない時とでfrom,toがいい感じで入れ替わる…みたいな実装を考えた結果from,toの入れ替え処理が怪奇なことになってます。
先にテストありきで進めていかないとダメですね。
まだ精進が足りないです。
app/console cache:clearするときは--no-warmupオプションつけると幸せ
先日行われたSymfony2勉強会に参加してきました。
会場を提供してくれたZynga Japanさん、企画開催をしてくださったスタッフの皆さん、プレゼンを発表された方々、一緒に参加した皆さんに感謝です。すばらしいイベントだったので今後も参加していきたいですね。
さて、symfony1を使っている方がSymfony2をさわって一番最初につまづくのがsymfony ccに変わるapp/console cache:clearの挙動だと思うんです。
symfony1でcache:clearを行うとcacheディレクトリ以下のファイルを全削除して終わりだったのですが、Symfony2のapp/console cache:clearを動かすとcacheディレクトリ以下のファイルを消した後に再作成を行います。
その結果webサーバーの実行ユーザーとapp/consoleを実行したユーザーとが違う場合、書き込み時などに権限が云々とエラーが発生してしまいドハマリします。自分はつまづきました。
yamlの記述間違いがキャッシュされてしまうのでクリアする、しかしブラウザ上で確認してみるとキャッシュファイルへ書き込み権限でエラーになる、そんな悲痛な叫びがワークショップでも聞こえました。
僕は 男は黙ってrm -fr app/cache/* などと物騒なことをつぶやいてみたりもしたのですが、あまりにも物騒です。まねしちゃだめです。
こんなときにはno-warmupオプションを使います。
php app/console cache:clear --no-warmup
このオプションをつけることでファイルの再作成を行わなくなります。
実際にはどんな風に動いているのか、
プロジェクトディレクトリ/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.phpを覗いてみるとわかります。
該当部分の抜粋です。
<?php .. $realCacheDir = $this->container->getParameter('kernel.cache_dir'); $oldCacheDir = $realCacheDir.'_old'; if (!is_writable($realCacheDir)) { throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir)); } if ($input->getOption('no-warmup')) { rename($realCacheDir, $oldCacheDir); } else { $warmupDir = $realCacheDir.'_new'; $this->warmup(!$input->getOption('without-debug'), $warmupDir); rename($realCacheDir, $oldCacheDir); rename($warmupDir, $realCacheDir); } $this->container->get('filesystem')->remove($oldCacheDir);
というわけで、no-warmupオプションをつけると幸せになれるよというお話でした。
……ときにapp/console ccとか動かすパッチはニーズがありますかね?あれば書いてみます。