Capistrano(カピストラーノ)で sudo が使えない問題

CapistranoのGetting Startedを行なっていて、sudo が利用できない問題に直面しました。

実行環境

Capisranoを実行するサーバ

OS CentOS6
OpenSSH OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
Ruby ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
rubygems 1.3.7
Capistrano 2.9.0
net-scp 1.0.4
net-sftp 2.0.5
net-ssh 2.2.1
net-ssh-gateway 1.1.0
highline 1.6.2

デプロイ対象サーバ(IP を 192.168.100.200 とします。)

OS CentOS6
OpenSSH OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
Ruby ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
rubygems 1.3.7

再現

% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1
  * executing `invoke'
  * executing "sudo -p 'sudo password: ' df -h"
    servers: ["192.168.100.200"]
    [hoge@192.168.100.200] executing command
*** [err :: hoge@192.168.100.200] sudo
*** [err :: hoge@192.168.100.200] :
*** [err :: hoge@192.168.100.200] no tty present and no askpass program specified
*** [err :: hoge@192.168.100.200] 
    command finished in 53ms
failed: "sh -c 'sudo -p '\\''sudo password: '\\'' df -h'" on hoge@192.168.100.200

SUDO=1 を外せば実行可能です。

% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200
  * executing `invoke'
  * executing "df -h"
    servers: ["192.168.100.200"]
    [hoge@192.168.100.200] executing command
 ** [out :: hoge@192.168.100.200] Filesystem            Size  Used Avail Use% マウント位置
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root
 ** [out :: hoge@192.168.100.200] 50G  3.3G   44G   8% /
 ** [out :: hoge@192.168.100.200] tmpfs                 2.0G     0  2.0G   0% /dev/shm
 ** [out :: hoge@192.168.100.200] /dev/sda1             485M   33M  427M   8% /boot
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home
 ** [out :: hoge@192.168.100.200] 92G  1.5G   86G   2% /home
    command finished in 48ms

つまり、下記もできないということ。仮想端末が割り当てられないようだ。

% ssh hoge@192.168.100.200 'sudo df -h'
sudo: no tty present and no askpass program specified

解決方法1 : 仮想端末が割り当てられていないので ssh -t をつける

普通のshell

ssh の -t オプションは強制的に仮想端末を割り当てる。下記は、実行結果。sudo をつけて実行が可能。

ssh
% ssh -t hoge@192.168.100.200 'sudo df -h'
[sudo] password for hoge: 
Sorry, try again.
[sudo] password for hoge: 
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_testbudgearycontrol-lv_root
                       50G  3.3G   44G   8% /
tmpfs                 2.0G     0  2.0G   0% /dev/shm
/dev/sda1             485M   33M  427M   8% /boot
/dev/mapper/vg_testbudgearycontrol-lv_home
                       92G  1.5G   86G   2% /home
Connection to 192.168.100.200 closed.
capistrano

まず、default_run_options[:pty]=true が書かれた capfile を用意します。

default_run_options[:pty]=true

capfileを指定して実行します。

% cap -f capfile invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1
  * executing `invoke'
  * executing "sudo -p 'sudo password: ' df -h"
    servers: ["192.168.100.200"]
    [admin@192.168.100.200] executing command
 ** [out :: hoge@192.168.100.200] Filesystem            Size  Used Avail Use% マウント位置
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root
 ** [out :: hoge@192.168.100.200] 50G  3.4G   44G   8% /
 ** [out :: hoge@192.168.100.200] tmpfs                 2.0G     0  2.0G   0% /dev/shm
 ** [out :: hoge@192.168.100.200] /dev/sda1             485M   33M  427M   8% /boot
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home
 ** [out :: hoge@192.168.100.200] 92G  1.9G   85G   3% /home
    command finished in 70ms

解決方法2 : Defaults visiblepw

sshd に Defaults visiblepw を設定すれば 仮想端末なしでも sudo が許可されます。デプロイされる側のサーバで visudo して、下記のように加えて、ssh を再起動します。

#
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
# Defaults    requiretty
Defaults visiblepw

上記のところに パスワードが見えるので ssh -t 使ってくださいと書いてありますけども・・・。

ssh
% ssh hoge@192.168.100.200 'sudo df -h'
[sudo] password for hoge: xxxxxxx            ##←パスワード丸みえ
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_testbudgearycontrol-lv_root
                       50G  3.3G   44G   8% /
tmpfs                 2.0G     0  2.0G   0% /dev/shm
/dev/sda1             485M   33M  427M   8% /boot
/dev/mapper/vg_testbudgearycontrol-lv_home
                       92G  1.5G   86G   2% /home
capistrano

Capistranoの場合は、パスワードは見えませんね・・。

% cap invoke COMMAND="df -h" HOSTS=hoge@192.168.100.200 SUDO=1  
  * executing `invoke'
  * executing "sudo -p 'sudo password: ' df -h"
    servers: ["192.168.100.200"]
    [hoge@192.168.100.200] executing command
Password: 
 ** [out :: hoge@192.168.100.200] Filesystem            Size  Used Avail Use% マウント位置
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_root
 ** [out :: hoge@192.168.100.200] 50G  3.3G   44G   8% /
 ** [out :: hoge@192.168.100.200] tmpfs                 2.0G     0  2.0G   0% /dev/shm
 ** [out :: hoge@192.168.100.200] /dev/sda1             485M   33M  427M   8% /boot
 ** [out :: hoge@192.168.100.200] /dev/mapper/vg_testbudgearycontrol-lv_home
 ** [out :: hoge@192.168.100.200] 92G  1.5G   86G   2% /home
    command finished in 4008ms

おまけ1 : sudoで特定のコマンドをパスワードなしで実行できるようにする

例えば、visudo で下記のように設定して、sshd を restart ます。

%wheel        ALL=(ALL)       NOPASSWD: /bin/df

上記だと、/bin/df コマンドは wheelグループユーザに所属していれば パスワードなしで sudo 実行できます。sudo で実行したいコマンドがたくさんある場合は不向きですね。

おまけ2 : sudo 時の path

visudo で設定を見ると Defaults secure_path というのがあります。これは、sudo 時に下記のパスが設定されますが、例えば、gem コマンドが /usr/local/bin にあった場合は、sudo 時に gem コマンドが使えないということになってしまいます。そのため、Default secure_pathに pathを加えることで対応します。

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

アジャイルサムライ他流試合に参加してきました

2011/09/18(日)、オラクル青山センターにて行われた「アジャイルサムライ他流試合」に参加してきました。運営してくださった皆様、場所を貸してくださったオラクル様、参加してくださった皆様、貴重な時間を本当にありがとうございました。イベントは最初から最後まで本当に楽しく、勉強になりましたm(_ _)m

アジャイルサムライ他流試合の内容や風景については下記に十分すぎるほど記録してありますので、そちらをご覧いただくと良いと思います。

参加のきっかけ

Twitterのタイムラインを何気なく眺めているときに、このイベントを発見しました。私は「道場」に参加したこともなく、実は「アジャイルサムライ」の書籍はRubyKaigi2011の時に購入したのですが、読んでいませんでしたので、「よし、このイベントをきっかけに読もう!」と思ったのです。そして、イベントの前日に本を読み、こちらのブログを書きました。

アジャイルという単語のイメージが変わった

アジャイルサムライを読むまでの私は、アジャイルという単語は「ある手法のまとまりを表すもの」だと思っていました。しかし、アジャイルは「価値観、心構え」を表すことなのだと気づきました。「アジャイルは形容詞である」と kakutaniさんもおっしゃっていましたが、アジャイルの数々の手法は「価値観の理解なしには効果は薄い」のです。私はこちらのブログでそのことを表現しました。そして、イベント中は「私が思う価値観に抜け漏れはないか」というのを探っていました。大まかには抜け漏れはないと感じたのですが、言葉のニュアンスは変えたほうが良いなと感じたり、達人プログラマーを読めばもっと良くなりそうだなと感じたり、もう少し広く考えたほうがより良いものになりそうだなと感じましたので、価値観のリストは進化させていこうと思っています。

RubyKaigiとは違う雰囲気

RubyKaigiはRubyを書いているプログラマが多かったのですが、アジャイルサムライの参加者は言語はさまざまですし、普段プログラミングをしない人もいます。でも、(これはRubyKaigiでも感じますが)皆さんとても優しくて、情熱を持っていて、価値あるものを作りたいという思いが強くて、プロフェッショナルで、知識が深くて、プログラミングだけでなく、経営についてよく知っていたり、営業についてよく知っていたり、経営陣に事業をプレゼンしてボコボコにされてるんだとか、時間を作って毎週読書会をやっているだとか、素直に皆すごいなーと思います。これからも勉強させて頂きますm(_ _)m たくさんの人と話せて、お友達になれた人もいます。これからも宜しくお願いします。

最後に

シールを頂いたので、Macに貼りました!有難う御座いました!

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

アジャイルが語る。価値あるソフトウエアを届けるために必要な12の価値観

私は日頃から「価値あるソフトウェアを提供したい」「開発スピードを向上したい」「顧客も開発者も幸せな環境を作りたい」、そう思いながら開発を行なっています。それらを達成するために必要だと感じているのが、”顧客とプロジェクトメンバー全員”で「価値観(大切だと思うこと)を共有して納得すること」だと思っています。極端な話ですが、もし顧客が「予算も仕様も開発期間も開発メンバーも固定だ。遅れたら土日祝日を使って取り戻せ。残業代はもちろん支払わないぞ。そしてソフトウェアが役に立たなかったら買い取ってもらうからな。フハハハハ!」という価値観をもった顧客と契約(約束)できるでしょうか?価値観というのはとても大切なのです。

私はアジャイルについて、以前から興味を持っています。例えば下記のエントリーがその現れです。

今日は、書籍「アジャイルサムライ --達人開発者への道」を読みました。そして、私の過去の経験も踏まえて、価値あるソフトウェアをを届けるために必要な12個の価値観を抽出してみました。

1. 価値ある成果を届ける

「この機能は本当に必要なのか?」・・・プロジェクトの中で考えていますか?。顧客が提示してきた機能の一覧を、何も考えずに実装しようとしていないでしょうか。顧客によっては「とりあえずこの機能もつけておくか」と考えている場合もあります。「本当にこの機能は必要なのか?」そう感じたら、顧客とコミュニケーションを取りましょう。「今回のプロジェクトの目的はこうなのですが、この機能はなぜ必要なのでしょうか」ということについて議論しましょう。それは、開発が面倒だとか、そういう気持ちではなく、顧客に「本当に価値のあるものを届けたい」という気持ちで議論しましょう。「機能が多ければ良いというわけではない」というのは皆さんご存知だと思います。そのソフトウェアを使いやすくデザインするために、使われない機能を省くことはとても大切なことなのです。開発の保守性も高まり、今後の開発もしやすくなり、ソフトウェアが長生きすると思います。

2. 必要とあれば進路を変える

世の中は混沌としています。そして、変化の連続です。そんな混沌とした世の中に、プロジェクトの計画には秩序があり、それを乱すことは許されない。こんなことが可能でしょうか。だいたいのプロジェクトは混沌から生まれる変化を無視できません。秩序を乱すような現実が多々現れます。「見積より時間がかかる」「競合他社がこの機能をリリースした。だから、この機能のリリースを早めたい」「この機能は必要なくなった」「やっぱりこの機能が必要だと気づいた」「この機能を作るためには、この機能に影響があり、再検討が必要だと気づいた」・・・日々変化の連続です。世の中が混沌と動いている限り、曖昧な人間がソフトウェアを作っている限り、このような変化は必ず起こります。強いチームは、変化が起こったら、本当に顧客が必要としている価値を再検討し、必要とあれば計画を変更します。この機能を後に回せないのかなどを検討します(ちなみに価値というのは期日も含まれます)。チャールズ・ダーウィンも言っています「強い者が生き残ったわけではない。賢い者が生き残ったわけでもない。変化に対応した者が生き残ったのだ」。プロジェクトも同じです。変化や課題、リスクをキャッチする仕組みをチームに導入し(例えば、朝会で「今の課題は?」を発表する場を設けてもよいですね)、顧客と積極的にコミュニケーションを取り、変化に対応しましょう。

3つの真実
1. プロジェクトの開始時点にすべての要求を集めることはできない
2. 集めたところで、要求はどれも必ずといっていいほど変わる
3. やるべきことはいつだって、与えられた時間と資金よりも多い

アジャイルサムライ P13)

3. 顧客の期待をマネジメントする

顧客が提示する機能の一覧を見て、開発者であるあなたは何を思うだろうか。「ふーん、これ作ればいいのね。じゃ、さくっと作るか」と思うだろうか。もしくは、「これは本当に顧客にとって価値があるものだろうか」と考えるだろうか。先程も書いたが、「価値ある成果を届ける」ことが重要であって、「顧客が提示したものをただ作る」ことは重要ではないのです。つまり顧客を疑う必要があると思います。顧客は神ではないし、完璧に仕様を作れる存在ではありません。実はソフトウェアの利用者のことをわかっていないかも知れません。技術について良く分かっていないかも知れません。開発者側も「なぜこのソフトウェアが必要なのか」ということを、しっかりと理解した上で、顧客の期待をマネジメントする必要があります。プロジェクトやチームへの期待は一方的に「設定」して終わりじゃないのです。顧客と継続的にコミュニケーションをとり、本当に必要な価値を知り、日々の変化に対応しながら、期待をマネジメントする必要があるのです。顧客とコミュニケーションを取る中で「やっぱこの機能いらないよね」「この機能の方が皆が喜びそうだね」といったことはよくあることなのです。

4. 顧客も積極的に参加する

「何を作りたいのか」は、基本的には顧客が要求してくるものです。しかし、先程書いたように、開発側も「顧客の期待をマネジメント」する必要があります。「顧客の期待をマネジメント」するためには、顧客が積極的に開発チームとコミュニケーションを取る必要があります。例えば、「(開発チーム)この要求について質問したいのですが・・」「(顧客)あー、まぁ適当にやっといて」このやりとりを見てどう思うだろうか、良いソフトウェアが出来ると思うだろうか。価値あるソフトウェアを作るためには、当然ながら顧客の協力も必要となります。顧客が開発チームの質問に答え、開発チームにフィードバックしなければ、価値あるソフトウェアなど作れるはずもない。顧客は「真実の源」です。

5. チーム一丸となって成果責任を果たす

こんな会話を聞いたりしないだろうか。「これは顧客が欲しい機能ではなかったよ」「私はテスターですから、実装された機能をテストしただけです。私に責任はありません」このやりとりを聞いてどう思うだろうか。同じチームで仕事をしながら、自分の作っているものに自信や責任感を感じられるだろうか。アジャイルが持つ価値観はそうではない、「チームに参加している以上、成果に対して責任を持つ」これがアジャイルの価値観なのです。また、アジャイルのチームは、要求分析担当、設計担当、実装担当、テスト担当などと言う、旧来の「テストしかしない」「実装しかしない」というように、あらかじめ細かく定義された役割というものは基本的には用意しません。要求分析、設計、実装、テストを機能ごとに短いサイクルで回すので、すべてを1人で行うこともあります。もちろん人の強みを活かすというのもありますが、こだわり過ぎて、本来の目的である「価値あるソフトウエアを顧客に届ける」ことを忘れてはいけません。品質保証部門というものも存在しません、あなたが品質保証部なのです。「仕様が悪いから、こんな使われない機能ができたんだ」「テストをちゃんとしてないから、こんなバグが出たんだ」こういった声はアジャイルチームではありません。仕様に疑問を感じたら質問する、テストに不安があったら質問する、チーム内のすべての人が「本当に顧客にとって価値があるのか?」を問い続け、コミュニケーションを頻繁にとり、開発工程のそれぞれを密接に連携させながら、日々作業進めていくのです。縦割り組織ではなく、一丸となったチームなのです。

6. 継続した学習

アジャイルは従来のチームとは全然違う。先ほども書いたが、典型的なアジャイルチームには、あらかじめ決まった役割分担が存在しない。誰もがどんな役割もこなしている。何もかもが混沌と混乱のうちにあって、チームには階層も序列も欠けているとしか思えないのに、なぜか彼らは高い遂行能力を持ち、どうやっているのかはわからないが、質の高いソフトウェアを届け続けている。「私はプログラマだから要求分析については専門外だからやりません」「私は要求分析専門だから、プログラミングは知りません」こういった声は普通に聞こえてきそうだが、アジャイルなチームはそうではない。チーム全員が、要求分析〜開発〜テストを行う場合があるのだから、必要な学習はする必要があります。アジャイルなチームは、学習意欲が高く、責任感が強く、顧客に価値を届ける情熱を失わない・・・こういった人が最適なのです。こうしたチームは信頼され、権限を移譲され、煩わしい決済などはすっ飛ばし、開発スピードが上がります。こうした職能横断型チームの真骨頂は物事をこなしていくスピードにあります。プロジェクト期間中は同じメンバーで協力しあい、一丸となって仕事をこなしていく。アジャイルチームには、役割分担が曖昧であっても冷静に対処できるゼネラリストが居たほうがいいのです。スペシャリストが必要になるのは、発生した事態に対処するスキルが開発チームに備わっていない場合です(たとえばデータベースチューニング)。

7. プロジェクトのゴールやビジョン、チームメンバーについて全員が理解して合意する

プロジェクトの意義や目的をはっきりさせておけば、誰のために何をしたらいいのかよく分からない、といった混乱とは無縁になれます。また、ゴールやビジョン、プロジェクトの状況や背景、期日、必要な技術、予算等についてチームでよく話しあっておくこと。そうすれば、チームは状況に応じて適切な判断をくだせます。これは、プロジェクトの最初の段階で積極的に行う必要があります。プロジェクトの後半になり、取り返しが付かないところで、重要なことが発覚して途中でプロジェクト中断・・・このようなことを防ぐために、プロジェクトの最初の段階で「手ごわい質問」をどんどんしましょう。また、ステークホルダーに開発の状況や課題などの情報を積極的に提供しましょう。彼らにはプロジェクトを続けるかどうかを決断するための材料が必要です。

8. 関係者との信頼関係を築け

プロジェクトのご近所さんと会って、あらかじめ知り合いになっておきましょう。きっと、後になってから「挨拶しておいてよかった」と感謝することになります。たとえば、顧客と開発チームでソフトウェアを作っていたとする。その機能はとても膨大なアクセスログを生むため、顧客と開発チームで「データは半年以上前のものは消しましょう」ということになった。ソフトウェア開発も終盤、そろそろリリースかなぁと思っていた頃、会社の管理部にその話をしてみると「弊社はプライバシーマークを取得しているので、アクセスデータは1年間は保持することが必要なのですよ」と言われ、データの保存や機能について再検討することに・・・。こうしたことは、管理部とコミュニケーションが取れていれば、起こらないことなのです。プロジェクトコミュニティは考えているよりも常に大きいことを認識し、関係者を探して、信頼関係を構築しておくことはとても大切な事なのです。もし、管理部と信頼関係がなければ、この話を管理部が聞いても、無視して、後の祭りになるかも知れません。

9. 小さく考える

プロジェクトの期間が長くなればなるほど、失敗のリスクが増える。これは、私の少ない経験からでも分かりますが、ランディという経験豊富な方も同じ事を言っています。下記は書籍から引用したものです。

 ランディ・モットは世界的にも有名なウォルマートのデータウェアハウスと在庫管理システムの開発を手がけた。店舗マネージャが全米の店舗でポップターツのどの味が今一番売れているかをリアルタイムに把握できるようにした。彼は同じことをデルでもやった。在庫のだぶつきをすぐにわかるようにして、過剰在庫を値引きできるようにしたんだ。現在、ランディはヒューレット・パッカードのCIOとして、コストを10億ドル削減する社内業務改革プロジェクトを担当している。
ウォルマートやデル、ヒューレット・パッカードといった企業を助けるために、これまでにランディは適切にあの手この手を講じてきたわけだが、彼自身が打ち明けたところによると、そこには共通するひとつの秘訣があるそうだ。それは、開発サイクルが6ヶ月を超えないことへのこだわりだという。
ゴールのはっきり定まっていない大規模プロジェクトの問題は、果たされることのない約束が交わされてしまうことと、届けられる成果が不十分になりがちなことにある。「これも追加してよ!」と「この機能も必要なので・・・」がいつまでも続く。やがてコストはかさみ、見積は誰も気にしなくなる。ついには肥大化し過ぎた自らの重みに耐え切れなくなって、プロジェクトは崩壊する。
 ランディのITプロジェクトの守備範囲は6ヶ月以内だ。彼の見立てでは、これ以上の期間を要するプロジェクトは危険過ぎるというわけだ。もちろん、彼の手がけたITによる業務改革のすべてが6ヶ月で完了したというわけじゃない。彼はただ、長年の経験から身にしみてわかっているだけなのだろう。本当に大きな仕事を成し遂げようと思ったら、それをもっと小さな、制御できる単位へと分割しなければならないのだということを。
 ITプロジェクトの期間の見極め方について、ランディのプロジェクトマネジメントの秘訣とアジャイル手法は同じことを言っている。つまり、小さいほうがいい。そして、期間は6ヶ月以内であることが望ましい。

私の経験からすると、3ヶ月でも長い。しかし、それは私の技術、経験不足が大きく影響していると思います。1日も制御できない人が、数ヶ月も制御できるだろうか?それと同じで、私は1ヶ月でも制御するのは難しい。まだまだ、私は修行が足りないということです。長いプロジェクトでも、その人なりに、制御できる小さな範囲に分割して収めることが、とても大切なのです。

10. 文書に頼りすぎてはいけない

実際のソフトウェアプロジェクトで、重厚な文書化が要求を捉える手段として本当にうまく機能したことなんて一度もない。顧客は自分たちの欲しいものを手に入れることはほとんどなく、開発チームは求められたものを構築しきれない。ものすごい時間とエネルギーが文書化のために費やされるが、それは何を成し遂げるべきかを話し合うためじゃない。何を文書に書くべきかを話し合うことに費やされるんだ。しかも、ソフトウェアへの要求を表現する手段として文書に頼りすぎることに弊害はそれだけに留まらない。いくつか例をあげてみよう。

  • 変化に対処できない(「確かに半年前はそう言ったわよ!」)
  • 顧客の欲しいものに合わせるのではなく、仕様に合わせて作ることになる(「顧客がこの機能が欲しいと言っていますよ」「さっき仕様を凍結したばかりだ。とりあえず聞いておいて」)
  • 下手な推測や誤った前提を招き入れる(「半年後はたぶんこうなってるよね・・・?」)
  • 多くの時間を無駄にする(「3ヶ月もかけて作った私の要件定義書が日の目の見ないとはどういうことですか?」)

顧客がソフトウェアで実現したいものを表現する手段としては、文書だけじゃぁ貧弱すぎて使いものにならないことの方が多い。「文書に頼りすぎてはいけない」という教訓から得られる最も重要なアジャイル開発の原則の一つがこれだ。

「情報を伝えるもっとも効率的で効果的な方法はフェイス・トゥ・フェイスで話をすることです」

11. 見積もりは未来の正確な予想図ではない

見積もりをどうしても間違えてしまうことが問題なんじゃない(まぁ実際、間違えてしまうわけだし)。問題は、見積もりから本来そこにありもしないものを読み取ってしまうこと--つまり、見積もりを未来の正確な予測だと思い込んでしまうことにあります。
こちらにも書いたのだが、極端に言えば、前もって正確に見積もるなんて無理。だから私たちはあたかも正確に見積もれるかのような素振りをやめるべきなのです。
前もって見積もるときに、私達が欲しい答えはただひとつ。つまり「このプロジェクトをやり遂げられそうなのか?」。プロジェクトの初期段階での概算見積もりを信用しない。とはいうものの、プロジェクトを始めるのには予算が必要だし、プロジェクトにどんな成果が期待できるのかを見通しも立てねばならない。そのため、見積もるのだが、顧客にも「初期段階の見積もりは当てずっぽうだという前提を理解」してもらい「ソフトウェア開発の複雑さを認めてもらう」、そして「期日と品質のバランスを考慮して柔軟に計画を変更していく必要がある」ということを話し合い、理解してもらうことが必要です。

12. 「やり方」はたった1つではない

これまで、アジャイル開発の価値観について書いてきましたが、「開発のやり方」というのは1つではりません。アジャイルの価値観を理解してれば、あなたの開発現場に適した「やり方」というのは数えきれないほどあるのです。チーム構成メンバー、要求を作る人、ソフトウェアを使う人というのは、皆違うのですから。さらに、あなたの開発チーム独特の価値観もミックスされるでしょう。

 万人の認める唯一無二なる究極のアイスクリームのフレーバーが存在しないように、万人が従う唯一無二なる究極のアジャイル手法のフレーバーも存在しない。


 ・スクラムは、アジャイルプロジェクトを包んで、プロジェクトマネジメントの装いを与えてくれる運営手段だ。
 ・エクストリーム・プログラミングは、どんなアジャイルプロジェクトにも欠かせないソフトウェア開発のプラクティスを規律正しく実践する手法だ。
 ・リーンは、能率を挙げることをとことん追い求める。たゆまぬ改善を続ける企業のためのトヨタ生産方式だ。


 そしてこれに、君独自のアジャイル手法が加わる。家族旅行で予定していた遠くの遊園地に車で向かったら、改装中で休園だったらどうする?そのときの対処法だってここに含めたっていいだろう。
 アジャイル開発に関する書籍や記事はどれも、それぞれの著者たちが、自分たちのお客さんと実際に試してみた経験から学んだことを、ただ共有しているだけなんだ。本書もその例に漏れない。

アジャイルサムライ P14)

まとめ

リッツカールトンにはクレドと言われる価値観をまとめたカードがあります。弊社にはLR HEARTという価値観をまとめたカードがあります。サウスウェスト航空には「従業員第一、顧客第二主義」という価値観があります。なぜ企業は独自の価値観を構築するのでしょうか。それは、価値観が合う人同士で仕事を行うと、問題も少なく、決断が早く、安定して高い価値を提供し続けることができ、顧客からも信頼されるからなのです。開発チームにも価値観を導入すべきです。カードを作って毎日読み合わせても良いくらいです。アジャイルの価値観は、あなたの開発現場独自の価値観を構築する上での大きな柱となるのではないでしょうか。価値観は開発チームごとに千差万別でしょう。開発のやり方も千差万別でしょう。これがベストの価値観・やり方であるという銀の弾丸は存在しません。あなたが、あなたの開発チームのために大切だと思うことを考えてください。

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

あなたがプログラミングの時に利用しているフォントは?というアンケートをTwitter上でやってみた

タイトルのようなアンケートTwitter上で行ってみました。10個回答が集まりました。もっと集まるかなぁと思ったのですが、意外と集まらないものですね…。やり方がまずかったのか、質問そのものが良くなかったのか・・・。とにかく、10個の回答を得ましたので、内容を確認しようと思います。ちなみに、半永久的に募集しておりますので、どしどしフォームから回答お願いしますm(__)m

アンケート内容

まだまだ募集中です! => http://t.co/iK3uvgI

アンケート結果

まずは、アンケート結果の確認です。 => http://t.co/P6s5uSY 空白が1つありますが一応入れます。

Timestamp あなたがプログラミングの時に利用しているフォントは?
9/12/2011 13:00:01 Lucida Console
9/12/2011 13:14:57 Menlo
9/12/2011 13:30:47 Ricty
9/12/2011 23:51:39 Osaka-等幅
9/13/2011 1:10:17 Consolas
9/13/2011 1:11:04
9/13/2011 1:17:04 Ricty
9/13/2011 1:27:18 Consolas
9/13/2011 8:06:16 Osaka-等幅
9/13/2011 9:36:51 メイリオ

集計

Ricty 2
Osaka-等幅 2
Consolas 2
Lucida Console 1
Menlo 1
メイリオ 1
1

グラフ

次からは、それぞれのフォントについて詳しく見ていきます。

Ricty


プログラミング用フォント Ricty
リクティと読むのですね。上記ページのはてなブックマーク数がものすごいですね。もしかして、超人気のフォントですか?はてなブックマークのコメントを見ると良いという評価が多いですね。「全角スペースの可視化」が良いというコメントが多いですね。最初のはてなブックマークが 201/04/18 ですので、この辺りにリリースされた新しいフォントでしょうか?

はてブのコメントを抽出すると特徴がわかりますね。

  • linux向けだけどwindowsでも使える。
  • RictyLinux 環境での研究・開発に適したフリーのプログラミング用 TrueType フォント
  • 全角スペースの可視化
  • Ricty (リクティ) は研究・開発のツールとして製作されたフリーの TrueType フォントです。C、C++FORTRANPythonPerlRubyAWKシェルスクリプトMakefileLaTeX など、Linux 上でのコーディングにおける使用を想定
  • ライセンス違反のため、TrueTypeフォントの配布を中止
  • Xfce Terminalでは10ptだと少し細い。12ptで丁度良いかも
  • 秀丸エディタで使ってみたけど12pt以下では漢字が潰れて視認できないなあ…
  • Vistaにインストールしてみたが12ポイントだと潰れる……
  • Inconsolata + Migu 1M、半角/全角比が1:2、全角スペース可視化、Winではgdi++系必須
  • 東大のシステム創生の人が作ったプログラミング用フォント
  • Inconsolata + Migu 1M (= M+ 1M + IPAゴシック)

Osaka-等幅


(※上記の画像はFirefoxのフォントをOsaka-Monoにしてキャプチャしました)
Osaka (書体) - Wikipedia
上記によると、OsakaフォントはMac OS日本語版において標準フォント、システムフォントとして使われた日本語フォントで、現在のMac OS Xにおいてもヒラギノフォント各種とともに標準でインストールされている。とありますね。知らずとお世話になっていそうです。私のMacには Osaka.ttf と OsakaMono.ttf が入っていました。ちなみに、私のMacFirefoxは Hiragino Kaku Gothic Pro でした。Osaka-等幅(Osaka-Mono)とは「平成角ゴシックとMonacoの組み合わせ」と書いてあります。フォントは他のフォントと組み合わせてつくる場合があるのですね。知りませんでした…。シェアは広そうですが、プログラミング用というわけではなさそうですね。

Consolas

上記の記事を見ると、Consolas は「プログラミング用」なのですね。フォントにはプログラミング用とそうでないものがあるのですね。Consolasマイクロソフトが出しているようですね。マイクロソフトのダウンロードセンターにもありました。対応システムは当然Windowsとなっています。でも、Macでも使えるみたいですね。http://studiokdf.com/blog/2009/06/1.html ぐぐってみるとけっこう出てくるので、愛用者が多い印象を持ちました。Consolas - soundscape out

Lucida Console


Lucida - Wikipedia
Lucidaというフォントがあり、その1つのようです。WindowsMacに標準インストールされているようです。実は私はこれを使っているのですが、なかなか気に入っています。Lucida Console の Facebookページを見つけました。

Menlo


(※上記の画像はFirefoxのフォントをMenloにしてキャプチャしました)
http://d.hatena.ne.jp/kanotomo/20090828/1251469553
上記によると、MenloはSnow LeopardXcode標準フォントだそうです。プログラミング用フォントということですかね?

メイリオ


メイリオ - Wikipedia
上記によると、「Windows Vista 以降のマイクロソフト製 OS に標準で搭載されており Windows XPWindows Server 2003 までの Microsoft Windows において利用されてきた MS UI Gothic に代わる、新しいシステム用フォントとして提供されている。」とうことで、こちらもWindows用ですね。とはいえMacで使ってみようという記事もありました。非公式だけど、Mac用のメイリオがあるようですね。メイリオフォントをOSXで使う。 – THE ROAD AHEAD

まとめ

アンケートの回答はあまり集まらなかったけど、フォントにうとい私には非常にためになりました。そもそも、「プログラミング用」フォントという存在を知りませんでしたし、「フォントは他のフォントと組み合わせて作っている場合がある」など知ることが出来ました。ご回答下さり有難う御座いました!まだまだ募集中です! => http://t.co/iK3uvgI

Rails 2.3 で acts_as_paranoid を使ってみた

Railsで論理削除を行う方法の1つとして、acts_as_paranoidというプラグインがあるので、Rails2.3で試してみた。なお、rails3用にはrails3_acts_as_paranoidがあるようです。

acts_as_paranoidとは?

データベースのテーブルのカラムに deleted_at を作って、deleted_atに日付があれば論理削除された状態、deleted_at が null なら削除されていない状態というのを管理してくれるプラグイン

install

$ cd RAILS_ROOT
$ ruby script/plugin install git://github.com/technoweenie/acts_as_paranoid.git

データベースを作成

migrationを作成して、カラム名 deleted_at、属性 datetime を持つテーブルを作成します。

  • ./db/migrate/001_create_table_hoges.rb
class CreateTableHoges < ActiveRecord::Migration
  def self.up
    create_table(:hoges) do |t|
      t.column :name, :string, :null => false
      t.column :deleted_at, :datetime
    end
  end

  def self.down
    drop_table :hoges
  end
end

モデルに宣言

class Hoge < ActiveRecord::Base
  acts_as_paranoid
end

論理削除されるか実験

$ ruby script/console
Hoge.new(:name => "fuga").save
true

Hoge.find(:all)
[
    [0] #<Hoge:0xb75546ac> {
                :id => 1,
              :name => "fuga",
        :deleted_at => nil
    }
]

Hoge.destroy_all
[
    [0] #<Hoge:0xb755091c> {
                :id => 1,
              :name => "fuga",
        :deleted_at => Fri Sep 02 19:40:30 +0900 2011
    }
]

Hoge.find(:all)
[]

Hoge.find_with_deleted(:all)
[
    [0] #<Hoge:0xb753e820> {
                :id => 1,
              :name => "fuga",
        :deleted_at => Fri Sep 02 19:40:30 +0900 2011
    }
]

その他の使い方

こちらを見ると分かります。

    # Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the current timestamp.
    # This assumes the table has a deleted_at date/time field. Most normal model operations will work, but there will be some oddities.
    #
    # class Widget < ActiveRecord::Base
    # acts_as_paranoid
    # end
    #
    # Widget.find(:all)
    # # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
    #
    # Widget.find(:first, :conditions => ['title = ?', 'test'], :order => 'title')
    # # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test' ORDER BY title LIMIT 1
    #
    # Widget.find_with_deleted(:all)
    # # SELECT * FROM widgets
    #
    # Widget.find_only_deleted(:all)
    # # SELECT * FROM widgets WHERE widgets.deleted_at IS NOT NULL
    #
    # Widget.find_with_deleted(1).deleted?
    # # Returns true if the record was previously destroyed, false if not
    #
    # Widget.count
    # # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL
    #
    # Widget.count ['title = ?', 'test']
    # # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test'
    #
    # Widget.count_with_deleted
    # # SELECT COUNT(*) FROM widgets
    #
    # Widget.count_only_deleted
    # # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NOT NULL
    #
    # Widget.delete_all
    # # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36'
    #
    # Widget.delete_all!
    # # DELETE FROM widgets
    #
    # @widget.destroy
    # # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36' WHERE id = 1
    #
    # @widget.destroy!
    # # DELETE FROM widgets WHERE id = 1
    #

関連モデルとの関係

関連モデルにも宣言してあれば、一緒に論理削除してくれます。参考

注意点

参考

残念な事に、acts_as_paranoidはsave(createやupdate)までは面倒を見てくれません。save時には全件を対象に一意の調査してしまうのです。
これを回避するには:scopeを指定してしまうのが良いでしょう。

いまさら、RubyKaigi2011を振り返る

2011年7月16日(土) 〜 18日(月) に開催された、RubyKaigi 2011から、もう一ヵ月以上経つのですね。いまさらですが、RubyKaigi2011をつらつらと振り返り、感じたこととメモを残します。

私はRubyKaigiに過去2回参加(2010年筑波2009年東京)していて、今年で3回目です。去年に引き続き個人スポンサーとして参加致しました。今年もとても楽しく、学ぶことが多く、たくさんの人とお話できました。RubyKaigi2011を運営してくださった皆様、スポンサーの皆様、有難う御座いました。

RubyKaigiは1年に1度、日本にRubyist達が全世界から集まる場所です。RubyKaigiの開催により再会できた人、憧れの人に会えた人、インターネットごしでしか知らなかったのにリアルになった人・・・こうした機会というのは多くないです。RubyKaigiはこうした機会を設けてくれています。Rubyコミッタがこんなに集まる会議はなかなかありません。海外のスターエンジニアと出会えることもなかなかありません。たこ焼き仮面さんの日本語キーノートはなかなか見れません。Ruby2.0の開発はtrunkでやろうなどといった話もなかなか聴けません。角谷さんの価値とは何か?多様性は善であるという主張もなかなか聴けません。全世界からキーノートが集まり、選ばれたものだけが発表できるという、全世界レベルのキーノートが聴けるわけです。地域RubyKaigiにはないものがRubyKaigiにはあるのですよね。とても貴重です。ぜひとも来年も開催して欲しいと願っています。

Next version of Ruby 1.8 and 1.9のセッション

Next version of Ruby 1.8 and 1.9のセッションでは、「Ruby 1.8 has no future. We gonna use 1.9.」という言葉があって、もう1.8ではなく、1.9を使おうという話がありました。私はまだ1.8.6をメインにつかっており、そろそろ1.8.7をメインにしたいと思っていて、かなり遅れております。Railsでは、1.8.6 はサポート対象外となっていますし、そろそろ1.8.6 を卒業しなければと感じました。

クックパッドさんのセッション

Ruby を利用した大規模ウェブサービスの開発・運用では、クックパッドさんがRuby を用いてどのように開発・運用されているのかを話されていました。クックパッドさんのプレゼンは去年も聴きましたが、去年よりパワーアップしているのが印象的でした。メモしたことを箇条書します。※誤字脱字ある可能性あり。

  • Ruby 1.8.7
  • Rails 2.3
  • haml
  • sass
  • JQuery(Protope を jQuery に 変えた。ブログで検索すれば出てくる)
  • Passenger 2.2
  • MySQL 5.0
  • memcached
  • サーバ構成は定石(サーバ/インフラを支える技術)
  • キャッシュ / バーニッシュ 2.1.5
  • イメージサーバ EC2 に設置
  • Image serve => Tofu(Rails3で処理は書いている)
  • Upload Server on EC2
  • Rails3 => S3
  • URLの中で画像サイズ等を決めている。
  • Searcher
  • MySQL + Tritonnから変わった。
  • Solr に変えた理由。柔軟な検索が可能。早くなったわけではない。柔軟で開発がしやすくなった。
    • Facet(like group by)
      • 集合扱う
    • Boost Search
      • 重み付け検索
    • Dynamicfields
      • 動的なフィールド追加
  • Log Analytics
  • Speed
    • Ruby / Rails 遅い? Slow? 実際に遅い?実際には遅くないかも。No.
    • Cookpad は 200ms 以下を実現。定石をきちんと行うことで、スピードを維持している。
  • 早くする工夫
    • "Good はやらない。Bestのみ集中"
    • シンプルさを保つ
    • Keep it Simple
    • ほんとうに必要な機能のみに絞る
    • 無駄に複雑なことをやらない
    • キャッシュに乗りやすくなる
    • シンプルなクエリ
    • あとでやる(Async Loading)。非同期レンダリング
    • 36ms、195ms(第一レスポンスは 36ms、他の非同期の部分は 195ms )
    • Ruby Rails not slow.
    • ウェブオペレーション(日本の料理のインフラ)
  • クックパッドは 30人のエンジニア。
  • Railsアプリの多人数開発
    • 開発 Dev → デプロイ → フィードバック →(戻る)
    • これをどれだけ早く回すのかが大切。
    • Tests
    • Rspec 1.x
      • unit
      • functional
      • integration
  • 最近はUnit と integration を沢山書き、functional は少なくなってきた。
  • Integration のテストが大切。javascript のテストがかける。
  • テストの処理速度が遅い。20分かかる。ティータイムになる。
  • テストをリモート上で行った。
  • テスト用のサーバをアップして、remote spec ×4 server。テストの話は大江戸Ruby会議で話したよ
  • Deploy Rule
  • CIが通るか?
  • 皆テストを書く・実行するように
  • CIで動かないテスト = 将来的に価値がないテスト
  • 継続することの重要性
  • 新しい技術を導入する = CIで動くテストが書けるを認識
  • RubyStudy@Sapporo#18
    • カピトラーノ
      • デプロイ時にメッセージを記入
      • 新機能の追加・大きな変更
      • Skype による通知
  • Error のモニタリング
    • インフラモニターがあって、それで見てる。何があると、画面が真っ赤になる。
  • エラーログの監視システム
  • フィードバック
    • Extensionsを使っている
    • Rails拡張
      • 条件指定で有効化
      • 一部ユーザのみ限定公開
    • プロトタイプ開発向き
    • Spec を書かなくても良いルール(まずは作る)
        • 例外発生時”自動で無効化”(extensionが落ちても今の機能に切り替わるので安心)
  • 新機能の利用率を知れる。
  • 配置ディレクト
  • リリースしない決断したら、rm app/extensions/foo_bar
  • 近いうちに、クックパッドのブログで公開

2008年に聞いたクックパッドさんのセミナーでは、Rubyは1.8.6、Railsも2.0でした。バージョンアップを意識的に行っていることが伺えます。クックパッドさんはColdFusionからRuby on Railsへ移行するなど、開発の改善を常に考え進化しています。

私のところは、やっとこ基幹システムがRails2.3 になろうとしていますが、これはクックパッドさんの影響を受けていると感じています。数年前に作られたシステムをバージョンアップするというのは、簡単ではありません。バージョンアップするだけで、何ヶ月もかかる場合もあります。私のところはRailsMySQLとライブラリのバージョンアップを行うのに半年近くかかりました。表向きは何も変わらず、裏で変わるだけですので、ユーザからすると「半年もかけて何がよくなったの?」となります。クックパッドさんが以前言っていたことで、「クックパッドはこれから100年以上生き続けるサイトである。だから、バージョンアップにも対応し続ける。新しい機能は魅力だし、他の新しいサービスと勝負できなくなってしまう」。私はこの言葉を聞いて、バージョンアップの重要性を知りました。たしかに、開発をしていると「あの機能があれば、1行で終わるのになぁ」とか「ちょ、gem install xxx できないんですけど。。」みたいなことがたくさんありました。スピードはとても大切ですので、適切なペースを保つためにも、寿命の長いアプリは、定期的なバージョンアップは必要だと感じます。これからも、バージョンアップしてきます。

githubのセッション

こんどはgithubのセッションです。英語でしたので、メモしたこともかなり怪しいですが・・・メモを箇条書きで残します。※誤字脱字ある可能性あり。

  • BrowserMob
  • Pingdom
  • akamaiを検討
  • Measure backend Behavior
  • Capacity plan
  • Collented
    • Time Series Information
  • Nagios
    • Monitoring & Alerting
  • Custom
    • Redis Counters
  • Communicate
  • Propane
    • extendable JS
  • Campfire
    • searchble logs
    • streaing API
  • Hubot
    • door me, image me
    • distributed execution
  • Day to Day
    • how tools work togers
  • User Interaction
  • Error
    • Unavoidable
    • cotweet
  • Haystack
    • exception loggin
    • like Hap Toad
    • 例外頻度が見れる
    • stream in realtime
    • fwe users impacted
    • many users impacted
  • Respond
    • failures we may miss
  • continuous integration
  • Branch status
    • any branch, any time
  • Jenkins CI
    • Solid Backend
    • ブランチの状態も常にCIでチェックしている
  • Webhooks
    • janky
  • Trigger Build

たのしいRailsのセッション

たのしいRailsのセッションでは、Railsそのものを開発するためのTips等が紹介されていました。私もOSSに貢献しようと思っているものの、なかなか足が踏み出させていない分野です。自然と貢献できるようになっているのが良いと思っていますが、OSS開発の道には努力しないと乗れないなという感じもしています・・・。セッションを聞いた時のメモを箇条書きしていきます。※誤字脱字の可能性あり。

たのしいRails
  • Ride on someone else's "rails"
  • "rails" for yourself
  • "rails" for everyone => "rails" に乗って開発するのではなく、"rails" そのものを開発することが楽しい。
  • プラグイン開発(Development Rails plugins)
  • Rails本体開発(Development Rails
  • 自分以外のためにコードを書く場合、コミュニケーションが必要。That's called "social coding"
  • Social Coding は 人と直接コミュニケーションすること。つまり、The community につながる。
  • a Community
    • 日本Rubyの会
    • asakura.rb
    • => The Community ではない
  • The Community == The World
  • Code Ruby, and be a member of "The community"
10 Pro Tips

1. Read Rails
  read "git log" every morning

  git pull
  git log

  将来のRailsが分かる
  だれが作っているか分かる

  良いコード、悪いコードが分かるようになる
  良いコミットコメントが書けるようになる

2. Know the people

 だれに注目すれば良いかわかる

 Stalk them online
 github
 Twitter
 blog

 BTW
  @tenderlov

3. Imitate good commites

 良いコミットが見えてくる

 A Good commit
 ・Atomic
 ・With tests
 ・with a short commit comment telling
 ・what

 in English, of course
 将来のソーシャルコーディングで避けて通れない道、英語。

4. English

 Know these 26 letters
 Aware of the accents
 表音文字、アクセントの位置が重要(アクセントの位置を間違えると通じない)

 Watch Railscasts

5. Live on the edge

 Railsのコミットを見ていると、新機能をどんどん使いたい

 Bundler素晴らしい

6. Contribute to the documentation
 ドキュメントを書いて、コミットする。
 だれでも、コミットできる

 git clone Info/docrails

 一番被害が少なくて良い

7. Share your monkey patches

 自分で作ったモンキーパッチを世界にだそう

 ブログなどに書くのではなく、パッチを書いてpushしましょう

 fork rails, push ,and send a pull request
 普通の pull request でパッチを送れる

8. Start from a gem

9. write a good README

 自分のgemを作る

10. Attend RailsConf
 Railsはたのしい
 RubyConfより全然楽しい

11. write a book

 BDD
  Book
  Driven
  Development

Rubyマスターへの道

◯準備

1. いろんな分野があること
 これを理解しましょう。
 プログラミングは色々な分野がある
 Rubyならだいたいなんでも作れる

2. 時間がかかること
 とりあえず、10年くらいあれば、だいたい何でもうまくなる。
 継続しましょう。
 料理に似ている。
 実践しないとうまくならないこと
 わりと早い段階から(それなりのものが)手にはいる

3. 何でもできること
 コンピュータの中ではプログラにできないことは何も無い。
 Rubyがだめなら、Cで、cがだめならアセンブラで。

4. 何でも作れること
 何でも作れるプログラマ
 増え続ける分野?

 何でも作れる= 「勉強すればなんでも作れる」という自信のこと

◯初級編

5. ライブラリを知ろう
 ・組み込みライブラリ
  Array, String, etc.
 ・標準添付ライブラリ
  open-uri, tempfile, find, etc.

6. 身近な問題を解決しよう
 テキスト処理
 ファイル名の一括リネーム
 Excel(*.csv)の処理。 require 'csv'

◯中級編

7. 良いコードをかこう
 「美しさ」は宗教やオカルトではない
 美しさ = 圧縮された「良さ」

 Rubyらいしコードを書く
  「初めてのRuby」がおすすめ

 each より map を使う
  短くなる
  意図が分かりやすい
  デバックしやすい、保守しやすい

 読みやすいコード
  Rubyの特徴 = 読みやすい(脳にやさしい)

8. ブログをかこう
  最初は反応がなくてつまらない
  検索エンジンごしの誰かに向けて
  メモをまとめることは自分にとっても役立つ(考えをまとめる、あとで見直す)

 発表しよう
  小さなイベントから少しずつ大きく 
  他人の作ったものの話でも良い

 githubに置こう
  英語だとなお良い
  置いて損することはない

◯上級編

9. 中を開けてみよう

 gem のソースを読む
 gemを書き換える
  gem pristine rails
   もとに戻せる
 Rubyのソース

10. 他の言語を知ろう

 Rubyしかしらない = Rubyの特徴を知らない

◯マスター編

11. 人と違うことをしよう

 Rubyはまだまだいろんなことができる
 手分けをする

12. 生産的であるために
 やる気の問題
  諦める(やりたくなるまで待つ)
  とりあえず始めるとやる気がでる
  嬉しいことがあるとやる気が保たれる
   チケット駆動
   テスト駆動
  やらざるを得ない環境(喫茶店とか)

 生産力の問題

◯終りに
 Rubyマスターになるとなにか良いことがある?

 プログラミングの楽しみとは「動いた!!」ということ。

 「あんなに上手くできたら楽しいだろうな」?
   幸せは現在にしかない
   目の前のコードを楽しもう

  気づいたら、Rubyマスターになっていたというのが良い

Ruby遺産とレガシーコード修理技術

Ruby遺産とレガシーコード修理技術のセッションを聞いた時のメモを箇条書します。※誤字脱字の可能性あり。

  • 25年使われるソフトをメンテする方法
  • tDiary = 日記のソフト
  • 書籍:レガシーコード改善ガイドを使って、開発者の負担を減らしましょう。基本Javaの本なので、考え方をもらった。

1. 変更できるほど十分にコードを理解していない場合
 =>削除する
  ・昨日の追加は慎重に、削除は大胆に
  ・ユーザに求められていてもNoと言えることが重要 ・仕様の却下業

2. 変更する必要が、ありますが、どんなテストを書けばよいかわまりません
 =>仕様化テスト
  ・テストで壊してはいけない骨格を作る
  ・ユニットテスト
  ・エンドツーエンド 
  ・インテグレーションテスト
  ・capybara

3. どうすれば何も壊していないことを確認するのか
 ・沢山のRubyのバージョン(1.8.6, 1.8.7, 1.9.1, 1.9.2, 1.9.3, 2.0.0)
  ・コンパイラ任せ
 ・CI
  ・travis-ci
  ・githubにあれば使える

  • ユーザが開発者
  • 開発者の負担を減らして、新しいことに挑戦してもらう
  • 継続するためには、開発を楽しむことが重要「たのしいRuby」(スライドの背景)

まとめ、書籍:レガシーコード改善ガイドを使って、開発者の負担を減らしましょう。基本Javaの本なので、考え方をもらった。負担を減らし多分、新しいことに挑戦してもらいましょう(燃料投下)

テスティングフレームワークの作り方

テスティングフレームワークの作り方を聞いてメモしたことを箇条書きしていきます。※誤字脱字の可能性あり。
Ket Beck曰く、著者は新しいプログラミング言語に直面すると、xUnitを実装する。TF = テスティングフレームワーク

  • Rabbit(うさぎとかめのタイマーのあれ)
  • test-unit 2
  • Cutter
  • GaUnit
  • Pikzie

判断基準について
 判断基準があるとずいぶん楽
 判断基準を伝える人が少ない
  「盗む」は大変
  盗んでないでもっと先へ行け

大事なこと
 何でもできるものは目指さない
 ターゲットを考える
  誰が使うTF?
  なんのためのTF?

自然であれ
 気づいたらできていた
  AをしたらBになっていた
 思いついたことが正解
  BをするにはAでいい?

自然か考える
 一貫性がある?
 身近なものと同じ手順?
 身近なものと同じルール?

まとめ
 判断基準を決めること
 ターゲットを絞ること

写真集

今回はiPhoneではなく、Mediasで写真を撮りました。


今回のテーマである「最後のRubyKaigi」を示したうちわです。来年も開催されることを願っています。



ステッカーを沢山頂きました。


個人スポンサーでしたので、Tシャツもらえました。


日本全国から来ていますね!


アメリカ、南アメリカ、ヨーロッパ、オーストラリア、アジアから来ていますね!


懇親会は「サンシャイン60 58階 サンシャイン・クルーズ・クルーズ」で行われました。景色がよく料理も美味しく、楽しいひとときでした。


大ホールです。たくさんの素晴らしいセッションがおこなわれました。



アジャイルサムライの本にサインをいただきました!価値ある開発とは何か?と問い続けます。


RubyKaigi本当にありがとう。


クロージングでのシーン。スタッフに向けて、スタンディングオーベーションです。とても感動的でした。スタッフの方々、発表者の方々、参加者の皆様、本当に有難う御座いました!

first time to use ruby-prof

What's ruby-prof

profiler for ruby. would you see http://ruby-prof.rubyforge.org/

Install

would you see http://ruby-prof.rubyforge.org/. I installed version 0.10.7.

% sudo gem install ruby-prof

Usage

There are three ways of running ruby-prof.
http://ruby-prof.rubyforge.org/

The first : ruby-prof executable

for example.

% ruby-prof --printer=flat --file=result --mode=wall hoge.rb

hoge.rb

for i in 1..10000
  p i
end

result(cat result)

% cat result
Thread ID: -604468348
Total: 0.081816

 %self     total     self     wait    child    calls  name
 37.88      0.03     0.03     0.00     0.00    20000  IO#write
 27.31      0.07     0.02     0.00     0.05    10000  Kernel#p
 12.84      0.08     0.01     0.00     0.07        1  Range#each
 11.71      0.02     0.01     0.00     0.01    10000  Kernel#inspect
 10.14      0.01     0.01     0.00     0.00    10000  Fixnum#to_s
  0.08      0.08     0.00     0.00     0.08        1  Kernel#load
  0.03      0.08     0.00     0.00     0.08        1  Global#[No method]
  0.00      0.00     0.00     0.00     0.00        1  <Class::Object>#allocate
The second : ruby-prof API
% ruby hoge.rb

result(STDOUT)

Thread ID: -604386428
Total: 0.082106

 %self     total     self     wait    child    calls  name
 32.35      0.03     0.03     0.00     0.00    20000  IO#write
 28.93      0.07     0.02     0.00     0.05    10000  Kernel#p
 14.90      0.08     0.01     0.00     0.07        1  Range#each
 13.02      0.02     0.01     0.00     0.01    10000  Kernel#inspect
 10.79      0.01     0.01     0.00     0.00    10000  Fixnum#to_s
  0.01      0.08     0.00     0.00     0.08        1  Global#[No method]

hoge.rb

require 'rubygems'
require 'ruby-prof'

# Profile the code
result = RubyProf.profile do

  for i in 1..10000
    p i
  end

end

# print a flat profile to text
printer = RubyProf::FlatPrinter.new(result)

profile_options = {
  :measure_modes => [RubyProf::WALL_TIME],
  :min_percent => 0
}

printer.print(STDOUT, profile_options)
The third : require unprof
% ruby hoge.rb

result(STDOUT)

Thread ID: -604060798
Total: 0.084379

 %self     total     self     wait    child    calls  name
 33.02      0.03     0.03     0.00     0.00    20000  IO#write
 29.09      0.07     0.02     0.00     0.05    10000  Kernel#p
 14.07      0.08     0.01     0.00     0.07        1  Range#each
 13.25      0.02     0.01     0.00     0.01    10000  Kernel#inspect
 10.55      0.01     0.01     0.00     0.00    10000  Fixnum#to_s
  0.02      0.08     0.00     0.00     0.08        1  Global#[No method]

hoge.rb

require 'rubygems'
require 'unprof'

for i in 1..10000
  p i
end

Graph html

% ruby-prof --printer=graph_html --file=result.html --mode=wall hoge.rb

hoge.rb

for i in 1..10000
  p i
end

result

KCacheGrind

% ruby-prof --printer=call_tree --file=callgrind.out --mode=wall hoge.rb

hoge.rb

for i in 1..10000
  p i
end

result view on Windows.

I'm on

OS CentOS release 5.3 (Final)
ruby ruby 1.8.6 (2009-06-08 patchlevel 369) [i686-linux]
ruby-prof 0.10.7