音楽とお酒とものづくりと

Web初心者の新人エンジニア(園児neer)奮闘記

fuelphpのORMモデルによるDBアクセス時のデータキャッシュには要注意

最近がっつりハマってしまったfuelphpのORMモデルメソッド利用時の仕様について。


ORMのCRUDメソッドを利用してDBアクセスした場合、fuelのフレームワークがよかれと思ってアクセス時のデータをキャッシュしてくれます。
そして同じレコードに対するデータアクセスがあった場合には、そのキャッシュデータを返すという仕様になっているようです。


この仕様のせいでどえらいハマってしまったので、記録として残しておきます。


ORMのCRUDメソッド実行時の詳細なSQLクエリ実行の様子や、キャッシュを避けるための方法についてはQiitaにまとめて投稿しておりますので、そちらをご覧ください。
qiita.com



今回得た教訓としては、
・データの設定や実装が正しいのに、想定する結果とならない時はデータキャッシュを疑え
フレームワークを信用しすぎない
ということ。


この二つは連動しており、フレームワークの挙動を一切疑うことなく、「想定通りにいかないのは自分の実装が悪いからだ!」と信じきっていたため、原因追求に時間がかかってしまったと思います。
想定しない挙動によるエラーが起こった時には、多角的な視点を持って解決に臨むべきだと学びました。

あなたのプレゼンをワンランクレベルアップさせるスライドデザイン

はじめに

先日行われました勉強会にてスライドデザインに関する発表を行いました。
勉強会での質疑応答時や発表後、スライドデザインに関する質問をいくつか受けましたので、その内容について記載しておきます。


質疑応答

Q:1行のみのスライドで、文章を中央寄せにしているのはなぜか?

A:こっち方が見栄えとしてシュッとしているからです。(逃

Q:前の人にしか見えないという点から言うと、スライドの下の部分も後ろからは見えないと思うのですが

A:その通りです。特に大会場だと前の人の頭でスライドの下が見えなくなるのは
よくあります。なのでそういう場合は

主張したいことを一番最初に述べ(スライドの上に書く)、
その主張を補足する内容をその下に書く

という構成もよく使います。発表の環境によっては、できるだけスライドの下、
3分の1は使わない方が無難かもしれません。この構成のメリットとしては

後ろの人でもスライドが見える」こと、
言いたいことを最初に言い切るため、スライド中の主張が明確になる」こと

などが挙げられます。

Q:アジェンダを出すのと出さないの、どっちがいいの?

A:アジェンダを出すメリットとしては、話の大枠をあらかじめ提示することで、

プレゼン全体を通して何を喋ろうとしているのか、
そして今は何について喋っているのかが掴みやすくなる
こと

が挙げられます。特にそこそこ長いプレゼンだと、話題の切れ目がはっきりしないとグダりがちです(経験談)。聴衆に「あれっ、今何の話してんの?」と思われたが
最後、最終的に「よくわからんかった」という感想が返ってきてしまいます。
なので私はアジェンダを出し、その大テーマをスライド上部、青色の所に記載し、
常にこのスライドは何についての話なのかがわかるように作っています。

Q:ご清聴ありがとうございましたスライドについて

A:これは賛否両論あると思いますが、私は

「ご清聴ありがとうございましたスライド」は絶対に入れません。

理由は「そのスライドに情報量が全くない」から。聴衆としては別に、
そのスライドを見せられても何も嬉しくないですよね。それだったら、
「まとめ」スライドを一番最後にしておいた方が良いでしょう。

自分が伝えたかったポイントを少しでも長く聴衆に見せることができますし、
聴衆もプレゼンの主張点を振り返りやすくなります


最後に

もし他にも「これってどうなん?」という疑問がございましたら
お気軽にコメントしていただければ幸いです。

(自分の知識的に)答えられる範囲で回答させていただきます。

仕事・勉強・研究、何にでも使える「nu board」のオリジナル活用法

nu boardとは?

一言で言うと「ノート型の持ち運べるホワイトボード」です。


モノによるかもしれませんが、ページ数は8ページ。
見開きで使うとおよそ2倍のサイズになるため、メモやMTG、打ち合わせなど
様々な用途で使える非常に便利な一品となっております。


ちなみに様々なサイズがあるようですが、今回はA4を購入しました。
つまり見開きだと最大A3で使用することができます。


CANSAY nu board (ヌーボード) A4判 NGA403FN08

CANSAY nu board (ヌーボード) A4判 NGA403FN08


仕事でも勉強でも研究でも、何にでも使えるこのnu board。
今回は自分なりの活用法についてご紹介したいと思います。


nu boardの活用方法

その1:To Do管理

仕事において、やらなければならないことがたくさん溜まっていきます。
その溜まりに溜まる(?)タスクを、私はnu boardを使って管理しています。

【管理方法】

自分が今抱えている全てのタスクを付箋に書き出し、見開き1ページを使って
nu boardに貼っていきます。
なおタスクを書く時は、付箋1枚につき1つのタスクを書くようにします。


f:id:takaaki_z:20160709182841j:plain
※詳細なタスクはモザイクかけさせてもらってます。


「activity backlog」とはポモドーロテクニックに登場するキーワードで、
”タスク管理倉庫”みたいな意味で使われています。

スクラム等でもbacklogというフレーズはよく見かけますね。


そして次の見開きのページを
Today」「Doing」「Done
の3つのエリアに分割します。


f:id:takaaki_z:20160709182853j:plain


ー今日やるタスクはTodayにー
「Today」の領域には、今日1日で自分がこなすべきタスクを貼ります。
毎朝「activity backlog」の中から今日やるタスクを選定し、「Today」の領域に
貼り替ていきます。


そしてその日1日は「Today」の領域に貼ったタスクを全て終わらせるべく
仕事をこなしていきます。


ーいま取り掛かっているタスクはDoingにー
Todayの領域のタスクの中から、とりかかるタスクを決め、実行していきます。
その際、選んだそのタスクを「Today」から「Doing」に移します。


ー完了したタスクはDoneにー
そのタスクが完了した時には「Doing」から「Done」に移します。


そして新たに取り組むタスクを「Today」から「Doing」に移していきます。

このようにタスク管理を行っています。


このタスク管理方法では、ポモドーロテクニックも合わせて実施しています。
ポモドーロテクニックを導入することで自身のタスクに関するメトリクスを
集めることができ、業務プロセス改善につなげていくことができます。


なおポモドーロテクニックについては過去のエントリーをご覧ください。
takaaki-z.hatenablog.com



その2:個人KPTボード

私は現在、KPTを用いて個人的な業務プロセス等の改善を行っています。


KPTの具体的な方法についてはググればすぐに出てくるので、
細かい説明は割愛しますが、ざっくりまとめると、


Keep:今後も続けていきたいこと
Problem:改善すべきこと
Try:改善すべきことに対するアクションプラン


を一定期間ごとに振り返っていく方法です。


これをnu boardの見開き1ページを利用して管理しています。


f:id:takaaki_z:20160709182845j:plain


私は1週間という期間でKPTによるふりかえりを行い、
その結果をnu boardに貼り付け管理しています。


そして、これ、Keepを続けていると、
今後も続けていきたい!と思っていたことが自分のアタリマエになってきます。


つまり意識しなくてもそれができるようになってくるわけですね。


そうなった時に、この項目はもはやKeepではなく自分の中でのRuleだ!
ということでRuleの領域を作成し、
アタリマエとなったKeepをRuleの領域に移動させていきます。


f:id:takaaki_z:20160709182849j:plain
※ちなみにホワイトボードのページ以外にも
透明なクリアシート黒い普通の紙のシートが挟んであり、
それらを活用して見開きのページ数を確保しています。

その3:ホワイトボード

ToDo管理、個人KPTに利用してもまだ見開き2ページ分のスペースが残っています。


ここはそのままホワイトボードとして利用しています。


書いた内容をそのまま残したい、というシーンが少ないので、
個人的には見開き2ページもあればホワイトボードとしては十分です。

どうしても残しておきたい場合には写メを撮って保存しておくようにしています。

f:id:takaaki_z:20160709183027j:plain


全ての項目に当てはまるnu board最大のメリット

上記で紹介した活用法、全てに当てはまるメリットが
持ち運びができる
ということ。


以前は会社でスチレンボードを使ってそれぞれ管理していたのですが、
やはり
・複数の役割を担うことができ
・それらに関する全ての情報を一元化できる
・しかもそれを持ち運びできる

というのがnu boardの最も素晴らしい点かと思います。


最後に

今回はnu boardの個人的な活用方法についてご紹介しましたが、
いかがでしたでしょうか?


他にも「こんな活用法がある!」などなどございましたら
教えていただけると幸いです。

vim上でphp-cs-fixerを実行するときにdry−runでdiffを確認してからfixを実施するための設定方法

はじめに

php−cs−fixerを実行する際、どこがどう変更されるのかを確認してからfixをかけたいですよね。
ターミナルから実行するときはオプションに--diffをつけてやれば問題ありませんが、vim上で実行するときはどうやったら確認できるのでしょうか。


php-cs-fixerのインストール

インストールはこちらを参考にして行いました。

php-cs-fixerのインストール
https://github.com/FriendsOfPHP/PHP-CS-Fixer

php-cs-fixerをvim上で実行させるプラグインのインストール
https://github.com/stephpy/vim-php-cs-fixer


vim上でのphp−cs−fixerの動作

f:id:takaaki_z:20160706223334p:plain

実際にvim上でfixerを動かすとこんな感じになります。どこをどう変更してくれるのかがわからないため、若干不安になります。

では、ひとつずつ見ていきましょう。


デフォルトのOption Available

まず、stephpy/vim-php-cs-fixerで指定できるオプションを確認してみると、diffの項目がありません。

" If php-cs-fixer is in $PATH, you don't need to define line below
" let g:php_cs_fixer_path = "~/php-cs-fixer.phar" " define the path to the php-cs-fixer.phar
let g:php_cs_fixer_level = "symfony"              " which level ?
let g:php_cs_fixer_config = "default"             " configuration
"let g:php_cs_fixer_config_file = '.php_cs'       " configuration file
let g:php_cs_fixer_php_path = "php"               " Path to PHP
" If you want to define specific fixers:
"let g:php_cs_fixer_fixers_list = "linefeed,short_tag,indentation"
let g:php_cs_fixer_enable_default_mapping = 1     " Enable the mapping by default (<leader>pcd)
let g:php_cs_fixer_dry_run = 0                    " Call command with dry-run option
let g:php_cs_fixer_verbose = 0                    " Return the output of command if 1, else an inline information.

どうやらデフォルトではdiffを有効化して変更箇所の確認を行うことは難しいようです。

なので今回はプラグイン本体に修正を加え、diffの結果を表示できるようにします。


プラグインの変更

プラグイン本体のファイルを確認してみます。
ファイルは~/.vim/bundle/vim-php-cs-fixer/plugin/php-cs-fixer.vimです。
デフォルトでは次のようになっています。

 44     if a:dry_run == 1
 45         echohl Title | echo "[DRY RUN MODE]" | echohl None
 46         let command = command.' --dry-run'
 47     endif


今回は一度dry−runを実行し、変更箇所を確認してから、実際にfixをかけるようにしたかったので、dry−run実行時にdiffを一緒に指定しました。実際には以下のように修正を加えます。

 44     if a:dry_run == 1
 45         echohl Title | echo "[DRY RUN MODE]" | echohl None
 46         let command = command.' --dry-run --diff'
 47     endif


このように変更を加えた後、オプションのdry_runとverboseの項目を1にしてやればOK。これでvim上からphp−cs−fixerを実行した時に、一度dry−runを走らせ変更箇所を確認したのちに、実際にfixをかけられるようになります。

" If php-cs-fixer is in $PATH, you don't need to define line below
" let g:php_cs_fixer_path = "~/php-cs-fixer.phar" " define the path to the php-cs-fixer.phar
let g:php_cs_fixer_level = "symfony"              " which level ?
let g:php_cs_fixer_config = "default"             " configuration
"let g:php_cs_fixer_config_file = '.php_cs'       " configuration file
let g:php_cs_fixer_php_path = "php"               " Path to PHP
" If you want to define specific fixers:
"let g:php_cs_fixer_fixers_list = "linefeed,short_tag,indentation"
let g:php_cs_fixer_enable_default_mapping = 1     " Enable the mapping by default (<leader>pcd)
let g:php_cs_fixer_dry_run = 1                    " Call command with dry-run option
let g:php_cs_fixer_verbose = 1                    " Return the output of command if 1, else an inline information.

修正後のfixerの動作

f:id:takaaki_z:20160706224121p:plain

このようにdry-runを実行したときに具体的な変更箇所(どこをどう変更するのか)を表示してくれるようになります。そしてこの変更でOKであればそのままコードをfixさせます。


注意点

なおこの方法では、diffの結果の表示色は全てオレンジとなってしまいます。ターミナル上でdiffの結果を表示させた時は変更前が赤、変更後は緑、みたいな感じで表示されているので、それに合わせに行きたいところですが、目的は達成されたので一旦ここまでとします。

PHPUnitにDBUnitを拡張してテスト用DBのデータを初期化させてみた

はじめに

テストを実行する際に、テスト用DBのテーブルのレコードをええ感じで初期化したいな〜という思いがありました。"ええ感じで"というのはそんなに深い意味はなくて、研修でwebアプリを作った時は、テスト実行時にDBのテーブルのレコードを初期化するコードをテストファイルの中にごちゃごちゃ書いてやっていたので、もっとスマートにやりたいなーというくらいのニュアンスです。
今回はDBUnitを導入してみました。

ちなみにPHPUnitも公式ドキュメントで

DbUnit を使うと、 データベースのテストにおけるこれらの問題をシンプルにする助けになります。

って言うてるみたいです。

DBUnitの導入

dbunitのインストール

まずはComposerでインストールします

"require": {
    "phpunit/dbunit": ">=1.2"
}

テスト用のクラスに継承させる

そしてテストクラスで

class Hoge_FugaTest extends PHPUnit_Framework_TestCase

と継承していたものを

class Hoge_FugaTest extends PHPUnit_Extensions_Database_TestCase

と書き換えます。

設定用メソッドの実装

次に上記のフレームワークを継承したクラスに以下の2つのメソッドを実装します。
getConnection()はテスト用のDBへ接続情報を与え、getDataset()はDBのテーブルへの初期データの情報を与えます。

    public function getConnection()
    {
        $db = \Database_Connection::instance();
        return $this->createDefaultDBConnection($db->connection(),'testDBname');
    }

    public function getDataSet()
    {
        return $this->createFlatXmlDataset(APPPATH."tests/defaultDataset.xml");
    }

'testDBname’はテスト用のDBの名前を指定するみたいですが、fuelphpでは各開発環境ごとに接続するDBの情報をconfigフォルダで管理しています。一応中の処理も見たのですが、おそらく?dbのDatabase_Connectionのインスタンスを作成する際にそのファイルを読みに行ってくれている?と思われるので、特に指定する必要はなさそうです。試しにtestDBnameを空文字にして試してみましたが、ちゃんと動いてくれました。

なんにせよ、これでテスト実行時にDBのテーブルのレコードを指定した値を用いて初期化してくれるようになりました。

初期データの指定

なお初期データは別のxmlファイルに切りだし、そのファイルのパスを指定してやればOK。
データは以下の様に記述します。

<?xml version="1.0" ?>
 <dataset>
     <users id="1" name="aho" password="ahopass" />
     <users id="2" name="boke" password="bokepass" />
 </dataset>

一点だけ詰まったのが、各フィールドに指定する値は、DBのテーブルで指定した型によらずクォーテーションで囲まないといけない様子。idとかの数値をそのまま書いてたらエラーで怒られました。

ポモドーロテクニックを導入して得られた3つの効果

ポモドーロテクニック導入

新人研修中に、タスクや時間管理の手法としてポモドーロテクニックを導入していました。本手法導入により得られた効果について社内勉強会で発表したので公開します。5分のLTだったので方法論や効果について詳しく言及できていませんがあしからず。


www.slideshare.net

TDD入門(テストを書いてみよう!&Test::SimpleとTest::Moreって?)

はじめに

これまでテストなんて1ミリも気にせず,やっつけでコーディングしていました.
が,しかし,テストを書くと幸せになれると聞いたので頑張って身につけようと一念発起.
めちゃくちゃ奥が深そうなので,段階的に,細かくアウトプットしていくつもりです.

TDDとは

Test Driven Development(テスト駆動開発)の略称.
プロダクトを作成する時,いきなりメインコードを書き始めるのではなく,プロダクトに必要と思われる機能のテストコードから書き始める開発手法.

テストから書くことによって様々な恩恵を得られるそう.たとえば,
・プロダクトの各機能は常に思った通りに動く
・冗長なコードが生じにくく,内部品質の向上につながる
などなど.

他にもたくさんあるそうですが,現段階で私自身が実感しているメリットはまだこれこれくらい.

テストを書いてみる

my $day=15;
print $day == 15 ? “ok!” : “no today is the 15th”;

実行します

perl -Ilib hoge.t

$dayの値が15であればokを,それ以外はnoを返します.

今回では内容が一致しているのでokが返ってきました.
試しに$dayの値を15以外でやってみると正しくnoが返ってくることがわかります.

Test::Simple

先ほどのコードを見て,まあテスト1個ならまだしも,いっぱいある時に全部printしていくのめんどくさ・・・てなりますよね.

そこでTest::Simpleを利用します

use Test::Simple;
my $day=15;
ok($day == 15);

先ほどprintでやっていたのがすべてok()に置き換わりました.
これで実行してみるとok 1 かnot ok 1が返ってきます.

またまた思うところとしては,これ,テスト数が少ない時だとまだマシですが,多くなったらどのテストが失敗したのかわかりにくいですよね.

そこで,ok()の第2引数にコメントを取ることができます.

use Test::Simple;
my $year=2016;
my $month=3;
my $day=14;

ok($year == 2016,"check year");
ok($month == 3,"check month");
ok($day == 15,"check day");

例えばこれで実行してみると,以下のようになります.

ok 1 - check year
ok 2 - check month
not ok 3 - check day
#   Failed test 'check day'
#   at test.t line 10.

なるほど,これでどのテストでエラーが起こったのかがわかりやすくなります.

さて,エラー箇所は特定できるようになりましたが,どういう結果になってテストが失敗したのかがわかりません.
今はハードコードで書いているため一目瞭然ですが,いろんなデータを処理しているとバグなどが原因で思った値が入っていないなんてことが起こりえます.

Test::More

そんな時はTest::Moreを使います.
名前の通り,Test::Simpleよりも機能がより多く使えるようになるそう.

use Test::More;
my $year=2016;
my $month=3;
my $day=14;


is($year,2016,"check year");
is($month,3,"check month");
is($day,15,"check day");

ok()関数ではなくis()関数を用いてそれぞれ第1引数にはチェックしたい値,第2引数に期待する値,第3引数にコメントを取ることができます.

これで実行すると

ok 1 - check year
ok 2 - check month
not ok 3 - check day
#   Failed test 'check day day'
#   at test.t line 10.
#          got: '14'
#     expected: '15'

3つめの日付のテストで失敗しており,さらに期待する値が15であったのに対し実際には14であった,ということが確認できるようになりました.

参考

以下の公式?サイトを参考にしました.和文に関して,エキサイト翻訳などにそのまま突っ込んだようなものしか見つからなかったので,内容は原文の翻訳をちょびっと意識しています.
Test::Tutorial - search.cpan.org