Google技術講演会in京都

7月6日にGoogle技術講演会in京都へ行ってきました。

とりあえず結論から

#=「Google最高!」

ハイアットリージェンシーとかえらい高級なホテルにカジュアルな服を着た人たちが集まるという面白い光景を見つつ。

軽食→講演→交流会

を楽しんできました。

ちなみに「京都」ということでGoogleの講演と同時にはてなの講演もありましたが、まぁ講演の話は誰か書いてくれてるだろうと思います。


「キャンセルする人」の割合が予想よりとても少なかったからか、交流会もかなり混雑してました。しかもそれくらい人がたくさん居たのに

#==知ってる人が一人も居ない

やっとkumatchさんを見つけましたが、kumatchさんも全然知ってる人居なかったようです。(学生や教員の方々が多かったような・・・という話も聞きました)

kumatchさんに今作ってるアプリのカオス具合を見せたりとかしてる内に・・・


#=なんと抽選の1番に当たりました。

すげー!抽選なんかお米とかしか当たったこと無いよ!
という訳でGoogleのデジタルフォトスタンドを頂きました。どうもAdsenceで貢献されてる方とかに送られてる商品みたいです。

という訳で当たったときに言えなかった一言を

#=Google最高!

あとはrhaco名刺を求められてrhaco名刺のモテ威力を味わったり、写真撮ってもらったりしました。

#==第2の結論:rhacoはモテ

さらにその後懇親会に紛れ込んだんですが、なんと人数約50人で居酒屋へ!良く入れたものだと思いますが、なんとか入ってGoogleはてなの方たちなどと色々聞かせて頂きました。

取り仕切って頂いたcuzicさんnitoyonさん

飲み代を負担していただいたGoogle様

#=本当にありがとうございました。

これからも関西でどんどんイベントなど開いてくれたらうれしいです!東京には興味あるけど、出来れば関西にGoogleが来てくれたら嬉しいなぁ〜〜〜!

逆引きrhaco22: rhacoのチュートリアル

rhaco本家にもチュートリアルはあるんですが、他のブログの方が紹介されている記事が素晴らしいので紹介します。下記の順序で読むとわかりやすいと思います。

チュートリアル順序:
1.環境作り(PDT) - sotarokさん
2.簡単な掲示板作成 - anatooさん
3.サンプルアプリblogkitを見る - sotarokさん

lingrで話題が出たので転載しておきました。

はじめて通天閣の下を通った

cocoitiさんが関西にやってくるということで会ってきました。何年も大阪に居るのに初めて通天閣の下を通りました。

酒が全然ダメなので、飯とかコーヒーになってスンマセン><。しかも喫茶店がなかなか見付からずに連れ回してスンマセン><。

色々話をして色んな刺激をもらって来ました。あれもやりたい。これもやりたい。そして「とりあえず」病を直したいー。

自分の中でなんとなく整理出来た点とかもあり、こういう「話合い」が出来る場は大事だなぁと思った夜でした。

逆引きrhaco(?)18:doctestを使う

※追記があるのでrhacoアプリ開発日誌も参考にして下さい。

doctestは「Pythonのdoctest便利ー!」と聞かされてカッとなって作った(パクった)テストツールです(違ってたら修正よろしく〜)。

便利な点は
1.コードとテストが同じファイル内にある
2.ユニットテストにテストが書いてある場合、どのユニットテストを見れば良いか分かる
3.テスト書いてないかどうかも分かる
4.trunkではドキュメントと同時にテストも表示されて例文代わりになって便利!
5.trunkではテストをファイル単位、フォルダ単位で自由に選べる

この4点だと思います。
早速簡単なのを書いてみます。
適当にプロジェクトを作ってlibrary/Hoge.phpを作ったとして

<?php
class Hoge {
  var $fuga;
  /**
  * class hoge
  * これはjavadocやphpdocsです
  * @author shigepon
  */ 
  function Hoge($fuga){
  /***
  * $h = new Hoge('rhaco');
  * eq('rhaco',$h->fuga);
  * neq('conveyor',$h->fuga);
  * neq('shigepon',$h->fuga,'テスト結果の欄にコメントを付けれますよ');
  * assert(isset($o->fuga));
  * //これはdoctestなので、コメントは//とか付けます
  */
    $this->fuga = $fuga;
  }

  function foo(){
  /*** #pass */
  //テストを「飛ばしたよ」と明示する場合
  }

  function bar(){
  //doctestを書かないとNONEと結果に表示されます。
  }

}
?>

という感じで書きます。doctestを行う手順は

1.setup.phpにアクセスする
2.上部の「test」リンクをクリックする。
これだけです。

さらに、
3.上部に実行するファイル、フォルダを選択できるコンボボックスがあるので、選択
4.executeボタンをクリック
で、指定したファイル、フォルダのテストが可能です。

使えるメソッドは
eq(予想する値,実際の値,表示するコメント)→予想値と等しければtrue
neq(予想する値,実際の値,表示するコメント)→予想値と等しくなければtrue
assert(実際の値,表示するコメント) →値がtrueならばtrue
の3種です。

rhacoでは気軽にテストを書けるので「転ばぬ先の杖」的に書いておけば幸せになれるかもしれません。

ちなみにRhaco自身のテスト内容はsetup.phpのrhacodocリンク、またテスト結果はRhacoフォルダ/_testapp/setup.phpのtestリンクから見ることが出来ますが、
非常にたくさん/*** #pass */が書いてあります。

/*** #pass */を埋めようと思う人は是非、lingrのrhaco-jaページなどで「テスト書くよ!」と言って下さい。

option要素を絞り込むjquery pluginを作ってみるメモ

rhacoの中の人の
このセリフ
をきっかけに、久しぶりにjqueryを触ってみました(最近はExtばっかりやってたので)。ついでに折角なのでplugin化してみました。以下は作成手順、ポイントなどのメモです。現在のrhacoのtrunkがjquery-1.2.1を使っていたので、1.2.1で作成しました。

実際に動いているのはrhacoのtrunk(rev 2762)以降のsetup.phpのrhacodocuなどで確認することが出来ます。

pluginの機能
・テキストフィールドへの入力値を用いてselectタグのoption要素を絞り込む
・フィールドが空になったらoption要素を元に戻す
・絞込みを行う最低文字数を設定できるようにする。

作成手順は
1.とりあえず機能を作る
2.まとめる
3.plugin化する
という流れにしました。
要は「とりあえずコードを書いてリファクタリング」です。

ソース
使用したHTML。最初はid指定の方が楽だったので、idを指定しています。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jquery-1.2.1.pack.js"></script>
<script type="text/javascript" src="filterOptions.js"></script>
<title>filtering test</title>
</head>
<body>
<form>
<input type="text" id="hoge" name="hoge" value="test" class="h" />
<select id="fuga" name="fuga" class="h">
<option value="111111">あああああ</option>
<option value="222222">あいいいい</option>
<option value="333333">あううううう</option>
<option value="444444">あいううう</option>
<option value="555555">あうえええ</option>
</select>
</form>
</body>
</html>

以下のソースは全てfilterOptions.jsで用意します。

1.とりあえず機能を再現する
とりあえず機能を再現できるかを試したかったので、「動けば良い」つくりです。楽するためにid指定にしています。onReady相当の場所に色々入れていたり、作りも何か変です。でも動きますw。まだ文字数指定は出来ません。

$(function(){var si = new searcher(jQuery('#hogyo'));
jQuery('#hoge').bind('keyup',function(){
var query = $(this).val();
if(query){
	jQuery('#'+si.id+' > not:(:contains('+query+'))').remove();
}else{
	jQuery('#'+si.id).replaceWith(si.clone.clone(true));
}})
});

var searcher = function(el){
	this.clone = el.clone(true);
	this.id = el.attr("id");
}

2.まとめる
設定を保存している箇所と絞り込む箇所が分かれてたりと構成が変なので、まとめます。

var refineOptions = function(select){
	var stock = {clone:select.clone(true),id:select.attr("id")};
	return function(el){
		var query = $(el).val();
		if(query){
			jQuery('#'+stock.id+' > :not(:contains('+query+'))').remove();
		}else{
			jQuery('#'+stock.id).replaceWith(stock.clone.clone(true));
		}
	}
}
$(function(){var rf = new refineOptions(jQuery('#hogyo'));
jQuery('#hoge').bind('keyup',function(){rf(this)})});

onReady部に書くコードの量が減って、機能と設定をまとめることが出来ました。

3.plugin化
機能をまとめることが出来たので、pluginにあてはめてみました。jQueryのplugin作成手順のページを参考にしました。

jQueryはチェインでどんどんつなげていくスタイルなので、渡される要素は複数あるケースが多いので、上の機能を複数の要素にあてはめる必要があります。idが存在しないケースもあるので、idが無い場合は作る必要があります。また上のケースではnewすることで関数をreturnさせ、clickイベントにbindさせていましたが、これも中に組み込んでしまいます。要は

・複数要素への対応
・plugin内で完結する

点に注意して、リファクタリングしました。

jQuery.fn.filterOptions = function(chars){
	var stock = [];
	this.each(function(i){
		if($(this).is("select")){
			if(!$(this).attr("id")) $(this).attr("id","_s"+i);
			stock.push({clone:$(this).clone(true),id:$(this).attr("id")});
		}
	});
	this.each(function(i){
		if($(this).is("input") && $(this).attr("type")=="text"){
			if(!$(this).attr("id")) $(this).attr("id","_i"+i);
			$(this).bind('keyup',function(){filter(this)});
		}
	});
	var filter =  function(el){
		var query = $(el).val();
		if(query && (query.length >= chars) ){
			$.each(stock,function(i){jQuery('#'+stock[i].id+' > :not(:contains('+query+'))').remove()});
		}else{
			$.each(stock,function(i){jQuery('#'+stock[i].id).replaceWith(stock[i].clone.clone(true))});
		}
	}
}
$(function(){jQuery('.h').filterOptions(4)});//4文字以上

と、こういう手順で作成することで、スムーズにpluginを作成できました。
プラグインにするぞー!」という目標があったおかげでリファクタリングも楽しくできたような気がします。Extは見た目の楽しさはあるけど、こういう楽しみは少ないなー。

結論:plugin作成は楽しい。jqueryも楽しい。

逆引きrhaco(?)15: ユニットテストを作りたい

その前にdoctestの解説をしろという話がありますが、今ちょうどやってるので、書いておきます。

ユニットテストをする場合は
1.まずユニットテスト用のフォルダを作ります。rhaco本体にならって_testappとします。
2.rhaco本体の_testapp下のindex.phpとsetup.php、__init__.phpをテスト用フォルダにコピーします。
3.rhaco本体にならって_testapp/setup/testsフォルダを作成します。
4.rhaco本体の_testapp/setup/testsフォルダから作成したtestsフォルダにunittest.phpをコピーします。

以上で最小構成が出来ました。たぶんこんな感じです。

_testapp
  index.php
  setup.php
  __init__.php
  setup
    tests
      unittest.php  

この構成のsetup.phpにアクセスするとrhacoのセットアップ画面が表示されます。
適当に設定して(ログをdeep_debugにすると吉)設定ボタンを押せば設定は完了です。

testと書いてあるリンクを押して下さい。

何も表示されませんが、とりあえずこれで動きました。
次にテストを書いてみます。セットアップの後はこんな感じになってるはずです。

_testapp
  index.php
  setup.php
  __init__.php
  setup
    tests
      unittest.php
  library
  resources
  work (logやキャッシュ設定をしてれば)

rhacoのテストはdoctestがベースなため、テストの呼び出し元を作る必要があります。ここではlibraryの下にtest.phpを作ってみます。

test.php(ファイル名とクラス名は一致させる必要があります)

<?php
  class test {
    function test(){
    }
    function testMethod(){
      /*** unit('sampleTest'); */
    }
  }
?>

テスト用ファイルをtests下に作ります。

sampleTest.php

<?php
  class sampleTest extends UnitTest {
    successTest(){
      $this->assertEqual(1,1);
    }
    failTest(){
      $this->assertEqual(1,0);
    }
  }
?>

これでもう一度動かすと、success 1, failure 1という結果が出て、テストが動いたことが確認できます。次は_testapp外のファイルをテストしたい場合について書きます。