メイン

2009年06月18日

[Ruby] 独習Ruby発売。

こんにちわ。ばたっちです。

ずいぶん、ご無沙汰のエントリになりますが、とりあえず生きています。(^^;


ご縁があって翔泳社様の「独習Ruby」の執筆をさせて頂いていたのですが、ついに書籍が発売されました!(パチパチ)

独習Ruby
独習Ruby

出版:翔泳社

本ができて来ると、「おおーっ、本物の本だー」って感動しますね。
本書いてるんだから、当たり前といえば、当たり前なんですが。。


Ruby関連本の出版ラッシュが、そろそろ落ち着いてきたかなというタイミングですが、こちらは「独習」シリーズということもあり、先端を行く人よりは、じっくりRubyを学習したい人に手にして欲しい本だと思います。
(Ruby関連本はハッカー気質な人を想定している本が多いようなので。。A^^;)

内容はRubyという言語の習得はもちろんですが、文法が分かってもオブジェクト指向プログラミングはできないので、

「じゃあ、オブジェクト指向でプログラミングするにはどうするのよ?」

というところにも踏み込んでみました。
Rubyも学べて、オブジェクト指向プログラマにもなれるというわけですね♪(^^)v

さらに、一歩先に行くための TDD(テスト駆動開発)やデザインパターンについても説明しています。


ちなみに、本書は序文に「達人プログラマ」「Programing Ruby」の Dave Thomas氏からメッセージを頂いています。(光栄!)

「Code Ruby, Be Happy!」

プログラミングを楽しむための言語であるRubyを、シンプルに表現していますね♪
こんな一文が書けるようになりたいものです。。A^^;


最後に、編集作業でお世話になりました翔泳社のU様、執筆作業のフォローして頂いた長瀬社長はじめ、社員の皆様、ありがとうございました。m(_ _)m

2008年07月23日

[Ruby][Rails] Ruby 1.8.7+Rails 2.0で。

こんにちわ。ばたっちです。

ちょっと前にRubyの脆弱性対応したときのメモ。時間経っちゃいましたが。

任意のコードが実行される脆弱性について
http://www.ruby-lang.org/ja/news/2008/06/20/arbitrary-code-execution-vulnerabilities/

Rails 2.0系、Ruby 1.8.6系で使ってたので、Ruby 1.8.6-p230に更新したのですが、何やらエラーが。

glibcでメモリ解放のエラーっぽいのが出てしまう。

当時は日本語の情報がまったく見当たらず(今はGoogleでいくつか引っかかりますね)、英語サイトではパッチが公開されたりしてたのですが、試す余裕&勇気がなくどうしようかと。A^^;

で、結局 Ruby 1.8.7に更新したのですが、Rails 2.0系って Ruby 1.8.7は対応していないので、少し手をいれないといけません。

Rubyで String#charsが定義されたのですが、Railsでは ActiveSupportで用意された charsを使わないといけないというのが問題の様。

config/environment.rbをちょこっといじるだけで、とりあえず回避できます。。ふぅ A^^;

参考: ruby 1.8.7 と rails 2.0.2
http://znz.s1.xrea.com/t/?date=20080606#p01

2008年06月23日

[Ruby][Rails] Ruby会議2008行ってきました♪

こんにちわ。ばたっちです。

Ruby会議2008行ってきました♪
私はRubyはRailsから入ったミーハー君なので、Rubyのコミュニティに触れるのは今回が初めて。A^^;

技術系のイベントってその技術が普及すると、企業などが入ってきて事例話とか、宣伝ばかりになってしまうけど、Rubyはまだまだギークが主役の楽しいコミュニティだと思いました。


詳しい内容はあちこちでレポートされていると思うので省略(話についていけなかったというのは秘密w)して、印象に残ったこととかをアウトプット。

一番はやっぱり、1日目のまつもとさん(matz)の基調講演が面白かったです。

まつもとさんの記事はあちこちで読んでたけど、生で声を聴くのは始めて。
話が面白く、上手で引き込まれるスピーチでした♪

テーマは「プログラミング梁山泊」。

梁山泊っていうのは、優れた人が集まる場所のことを言うそうで、これに例えて、


  • 技術者が集まり

  • 新しい技術が生まれ

  • 世界を変える


ような技術を「梁山泊」として、コンピューティングの歴史を振り返ります。

単なる仕事の道具であったり、技術うんぬんより結果に関心があるようなものは「梁山泊」とは言えないということ。

「梁山泊」には技術力より求心力が必要、UNIXは最初から優れていたわけではないけど、技術者が集まる「場」を提供できたからいいものができた。

つまりコミュニティが重要であると。φ(.. )

例として、LISP、UNIX、Smalltalk、Javaをあげ、そして次の梁山泊は「Ruby」だとつなげていきます♪

Rubyは、LISPやSmalltalkなどの過去の梁山泊を継承し、人や楽しさに注目といった感性を大事にするという特徴のあるコミュニティのようです。


次の梁山泊と言える理由のひとつとして、Rubyの実装系がたくさん出てきていることをあげていました。

Ruby1.8、1.9などのオリジナルなCRuby、JavaVM上で動かすJRuby、Smalltalkで動かす?Rubinious。
他、Ruby.NET、IronRuby、MagLev、。。

(ちなみに、まつもとさんを始めとする少数のCRuby開発陣に比べ、バックに巨大なJavaVM開発者の後ろ盾のあるJRubyはずるいよねって(こそっと)言ってましたw)

多様性をよしとするのはUNIXと似てると思います。
同じくLLなPerlやPythonには、複数の実装系が出ていない(PythonにはJythonというのがあるようですが)という比較をされていました。

でも、以前はRubyは複雑だから複数の実装系が出てくるのはありえないって言われてたそうですね。


また、講演後の質問にもありましたが、まつもとさんはMagLevという実装系に関心を持っているというのが印象的でした。

MagLevというのはSmalltalkのVM上で動くRuby?とかで、初の商用の実装系になるそうです。

なぜ、まつもとさんはMagLevにそんなに関心を寄せているのか?という質問に対し、SmalltalkやLISPはRubyの原点であり、そちらの方面からRubyへの逆のアプローチだからだということでした。

これはたぶん、Rubyを作ったまつもとさんならではの思いなんじゃないですかね。
かつての師に認められたような感覚といえば大げさかもしれませんが。A^^;


1日目最後のライトニングトークスも面白かったですね。

コードじゃなくて考え方をJavaからRubyなんだという発表では、プロジェクトの規模を自慢するのはバカがやること、コード数、開発人数が大きくなるのは、物事を簡潔にする能力に欠けている証拠だとか、バサッと切るのは気持ちよかったです。

3Dイメージによる、ピタゴラ装置の発表は斬新でしたね。Wiiリモコンでプレゼンってカッコいいす。

個人的にはtoRuby(栃木Ruby?)の方の発表がよかったです。
年を重ねても新しい技術に積極的に挑戦している姿を見て、「ああいう風に年を取りたい」って思った人は結構いるんじゃないでしょうか?(^^;


長くなってきたのでこの辺で。

他にも、

MacRuby (Macが欲しくなってしまう。。A^^;)

RESTとRuby and Rails (URIベースな設計大事だと思う。REST勉強中です)

iKnowや食べログなどのRails運用事例 (参考になります)

JPmobile (開発苦労話に感動。ぜひ使ってみたい)

GC(ゴミ集め)の話 (GC愛すばらしい。プレゼンのGCメソッドGJ)

とか面白かったです。すげー省略。A^^;


最後に運営スタッフのみなさん、お疲れ様&ありがとうございました。m(_ _)m

2008年04月18日

[Rails] RESTクライアントの認証を動的に切り替える。

こんにちわ。ばたっちです。

RESTアプリケーションはステートレスなので、認証が必要な場合は毎回リクエスト毎に認証が必要になります。

認証方法は HTTP Basic認証が推奨?されていて、Rails 2.0では Basic認証機能が強化(追加?)されてるようですね。

クライアント側でのリソースの参照に ActiveResourceを使う場合は、サイトのURLにユーザ名、パスワードを追加しておけばOKです。

こうしておけば、リクエスト時に Authorizationヘッダを追加してくれるんですね。

ところで、この site属性はクラススコープなので、リソース単位に一意になるんですが、複数のアカウントで切り替えたい場合(普通はないのかな?)にちょっと困ります。

ActiveResourceでは siteのURLを元に、connection属性(これもクラススコープ)を作っているようなので、これをいじればいいのかもしれません。

別の方法として、headers属性(ハッシュ、クラススコープ)というのがあって、ここにヘッダを追加しておくと、リクエスト送信時にヘッダに追加してくれるようです。

ということは、ここに Authorizationヘッダを追加してやれば、動的に認証情報を設定できるのかも。。

というわけで、以前作った MultiModelScope(see. [Rails] 複数のモデルに with_scope。)を真似て、MultiResourceScopeというのを作ってみました。

複数のリソースにまたがって、動的に認証を切り替えたいという場合に使えます。

こんなカンジに使うことを想定。

認証方法を変えられるようにしたり便利かも。A^^;

2008年04月16日

[Rails] RESTなサーバ/クライアントを試してみる。

こんにちわ。ばたっちです。

Rails 2.0の REST対応はは、RESTアプリのサーバ側の機能と、クライアント側の機能が入ってるんですね。

  • サーバ側 : ActionController::Resourcesとか
  • クライアント側 : ActiveResource
サーバ側では config/routes.rbに「map.resource :entry」のように書くだけで、CRUDな URLを生成してくれます。

例えば、コントローラで、

とすれば、Entryオブジェクト(ActiveRecord)を自動で XMLに変換して返します。
(ActiveRecordの to_xmlの結果をそのまま返すみたい。だからテンプレート不要。)

一方 ActiveResourceは、クライアント側で RESTで提供されているリソースを、まるで ActiveRecordのオブジェクトのように扱えるようにしてくれるクラス。

例えば、上記の showアクションのレスポンスとして、

のようなXMLを返す RESTアプリがあって、それを ActiveResourceで扱うと、

こんなカンジでアクセスできます。find()の裏では「GET /entries/1.xml」のように HTTP GETしてるんですね。
うーん、すごい。

さて、Railsが自動で作ってくれる CRUDなインターフェースがそのまま使えれば、とても便利なのですが、実際に RESTアプリを作ると考えると、少し工夫が必要になりそうです。

例えば、

  • クライアントの認証が必要な場合は?
  • ActiveRecordの idをプライマリキーにしない場合は?
という場合はどうするんだろといったカンジ。

まず、認証については、アカウント名+パスワードで認証するのであれば、URLにアカウント名、パスワードを含めてBASIC認証にするみたい。

なるほど。
ちなみに RESTの定義としてセッションなどにログイン情報を持たず、毎回のリクエストでリソースの参照を完結すべきだそうで、認証が必要な場合は認証情報も毎回送る形になるようです。

それから、APIキーを発行するだけのような場合、URLの後ろに「api_key=key1」のようにクエリパラメータをつけるのは RESTっぽくない気がするので、

http://api.example.com/api/key1/entries/1.xml

のように、URLのプレフィクスに入れる方法を考えてみました。
この場合では、ActiveResourceの siteにプレフィクスまでを含めた URLを設定すればできるようです。

次に、idをそのままプライマリキーに使えない場合。

例えば、外部の固定リソース(郵便番号情報とか)の上に RESTアプリをかぶせたりする場合、idをキーにすると外部リソースとの連携がしづらい。
例の Entryを日付をキーにしてとるような URLを考えてみる。

/api/key1/entries/20080415_001.xml

サーバ側では、config/routes.rbには以下のように設定します。
(ただし、Routing::RouteBuilderには、先日のエントリの修正をいれています。see. [Rails] routingの namespace。)

EntriesController#showには、{ :key => "key1", :action => "show", :date => "20080415_001" } のようなパラメータが渡されるので、うまく検索できるように実装します。(^^;

クライアント側では、この URLだと ActiveResourceの find(1)のような方法では取得できないのですが、ActiveRecordの findと同様、いろいろできちゃうのが find()メソッド。(^^)v

ActiveResource::Base#findメソッドには、:fromというパラメータで URLを直接指定することができるようです。 したがって、

のようにアクセスすることができます。
ちなみに、:fromパラメータには Request-URIを先頭から指定しないといけないようで、self.site に設定したプレフィクスには続けてくれないようです。

のようなメソッドを作るとよさそうですね。

他にも、element_pathという URLを作成するメソッド?があるので、そちらも使えそう。
Request-URIのプレフィクスが有効になるようです。
(こちらは逆に .xmlが勝手についてしまうので、外す方法が分かりません。A^^;)

以下はサーバとクライアントのログ。

サーバ側

クライアント側

プロセス間通信の実験みたい(プロセス間通信だけど)で面白い♪

でも、まだまだ試行錯誤ですねぇ~ (^^)/~

2008年04月14日

[Trac] TracGanttCalendarプラグイン for Trac-0.10(trac-ja)

こんにちわ。ばたっちです。

tidusさんの TracGanttCalendarというプラグインの Trac-0.10対応。

[Trac]TracGanttCalendarプラグイン
http://tidus.ultimania.org/diary/?date=20071020#p01


カレンダーとチケットの連携と、ガントチャートの描画ができるようになるプラグインです。
オリジナルは 0.11以降にのみ対応なのですが、インタアクト製の trac-ja(Trac-0.10.4)な環境で使いたかったので、移植してみました。

ロジック部分は 0.10と 0.11でそれほど変更なさそうなので、軽い気持ちで着手したら、テンプレートエンジンが ClearSilverってやつから、Genshiってのに変更になってて、実は差分がでかいということを知り、えらい目に会いました。A^^;

TracGanttCalendar 0.1(2008/4/12現在、trunkから取ってきた最新)をベースにしています。
(バージョンのつけ方がよく分からないので、0.0.1としています。)


以下、インストール方法です。

ファイルをダウンロード。
TracGanttCalendar 0.0.1

ファイルを展開。
> tar zxvf ganttcalendar-XXX.tar.gz

eggファイルを作る。
> cd ganttcalendar-XXX/
> python setup.py bdist_egg

eggファイルを pluginフォルダにコピー。
> cp dist/TracGanttCalendarPlugin-XXX-pyXX.egg /path/to/tracprj/plugins/

Apache再起動。
# /etc/init.d/apache restart

インストールが完了したら、トップのナビゲーションバーに、「カレンダー」と「ガント」が追加されます。


いまさら、0.10対応なんて必要な人いないかもしれないけど、どうぞ。A^^;


追記 (2008/4/24):
カレンダーのマイルストーン表示にエラーがあったので、修正版をアップしました。
(上のリンクからダウンロード可)


追記 (2008/4/25):
TracGanttCalendarのリポジトリにブランチ作成してもらいました♪
http://svn.sourceforge.jp/svnroot/shibuya-trac/plugins/ganttcalendarplugin/branches/0.10/

下記のコマンドでチェックアウトできます。


svn co http://svn.sourceforge.jp/svnroot/shibuya-trac/plugins/ganttcalendarplugin/branches/0.10/ ganttcalendarplugin

2008年04月09日

[Rails] routingの namespace。

こんにちわ。ばたっちです。

routing周りのコード見ていて気になったんですが。。
(Railsのバージョンは 2.0.1)

という部分は、

となるのが正しいんじゃないかと。。A-_-;;

  • namespace -> コントローラのプレフィクス
  • path_prefix -> URLのプレフィクス
  • name_prefix -> URL名のプレフィクス
と考えるとすっきりするんだけどなぁ。

routingのテストには path_prefixありのケースがない(resourcesにはたくさん)ようなので、どうあるべきかが分かりません。。うーん。A^^;

2008年04月02日

[Rails] 複数のモデルに with_scope。

こんにちわ。ばたっちです。

複数のモデルに対してあるカラムでフィルタリングしたい(ローカライズとか)と思って、ActiveRecordの with_scopeを調べてみました。

Rails 2.0からは with_scopeは protectedメソッドになっていて、外部からはそのままでは呼べなくなったんですね。
コントローラのフィルタを使う scoped_accessというプラグイン(舞波さん製)を使うのが主流なのかな?

scoped_access
http://wota.jp/svn/rails/plugins/branches/stable/scoped_access
http://wota.jp/ac/?date=20060105

どうも、複数モデルにまたがってスコープかけるという話はなさそうで、コントローラのフィルタにしてしまうのもピンとこない。

やりたいことはこんなカンジ。

  • 複数モデルにまたがって with_scopeしたい。
  • モデル外(コントローラとか)からスコープを指定したい。
  • モデル内で sessionは見たくない。
  • スコープ範囲のブロックを細かく指定したい。(旧バージョンの AR#with_scopeを直接呼ぶイメージ)
というわけで、以下のようなクラスを作ってみました。
中身は scoped_accessを参考にしてます。

たとえば、こんなカンジで使うことを想定。
複数モデルに ローカライズを行う例です。

すでにある方法でうまくできるのかもしれないんだけど。。A^^;

2008年03月31日

[Ruby] MechanizeでEOFError?

こんにちわ。ばたっちです。

WWW::Mechanizeでサイトを巡回していて、EOFErrorになることがあったので覚書。

エラーの内容は以下のとおり。


/usr/lib/ruby/1.8/net/protocol.rb:133:in `sysread': \
  end of file reached (EOFError)
        from /usr/lib/ruby/1.8/net/protocol.rb:133:in `rbuf_fill'
        from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout'
        from /usr/lib/ruby/1.8/timeout.rb:76:in `timeout'
        from /usr/lib/ruby/1.8/net/protocol.rb:132:in `rbuf_fill'
        from /usr/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
        from /usr/lib/ruby/1.8/net/protocol.rb:126:in `readline'
        from /usr/lib/ruby/1.8/net/http.rb:2017:in `read_status_line'
        from /usr/lib/ruby/1.8/net/http.rb:2006:in `read_new'
        from /usr/lib/ruby/1.8/net/http.rb:1047:in `request'
        from /usr/lib/ruby/gems/1.8/gems/mechanize-0.6.10/lib/\
  mechanize.rb:514:in `fetch_page'
        from /usr/lib/ruby/gems/1.8/gems/mechanize-0.6.10/lib/\
  mechanize.rb:185:in `get'
        from test.rb:19
正確なパターンは分からないのですが、以下のようにJavaScriptファイルの取得前後でエラーになるようでした。
  • 「http://~/test1.html」のように最初のページをGETする
  • 相対パス指定で次のページをGETする (A)
  • 相対パス指定でJavaScriptをGETする
  • backメソッドで履歴を戻る
  • 相対パス指定で(A)のページなどを再GETする
特定の条件で発生するのか、一般的なサイトで同じ動作をさせても再現できなくて、具体的なサンプルを示せません。。orz

直接関係あるかは分かりませんが、気になった点は次のとおり。

  • サーバがIIS
  • Content-Typeが「application/x-javascript」(通常は text/javascript)
結論を言うと、Mechanize の keep_alive を無効にするとうまくようです。 ※サンプルコードはイメージです。

原因がはっきりしないので気持ち悪いですが、とりあえずうまく行きました。(^^)v
同じような現象に会った人いるかな?

2008年03月28日

[MySQL][Rails] Lost connection to MySQL server during query

こんにちわ。ばたっちです。

Railsのユニットテスト中にタイトルのエラーが出ることがあります。
調べてみたら、結構話題になってるみたいですね。

http://d.hatena.ne.jp/Rommy/20070814/p1
http://idm.s9.xrea.com/ratio/2006/04/08/000406.html


ユニットテストのエラーを見てると、
「Message: ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query」
と、
「Message: Errno::ECONNREFUSED: Connection refused - /tmp/mysql.sock」
が交互に出ている。

DB接続が切断(mysqld再起動?)→DB接続失敗を繰り返しているみたいですね。


MySQLのマニュアルを見てみると、どうやら MySQLクライアント―サーバ間で大きなサイズの
パケットが送られると接続が切れるそうです。

MySQL 4.1 リファレンスマニュアル :: A.2.9. Packet too large エラー
http://dev.mysql.com/doc/refman/4.1/ja/packet-too-large.html

my.cnfの [mysqld]セクションの max_allowed_packet を 1M→16Mに変更してみたらビンゴ。


[mysqld]
  :
max_allowed_packet = 16M
  :

/etc/init.d/mysql restart でMySQL再起動したら、ユニットテストが通るようになりました。
よかったよかった。A^^;


(追記)

一時的にうまくいっていたようで問題が再発。。orz

mysqld.logを見てみると「mysqld got signal 11」が始まるログが吐かれていて、
thd->query at 0xXXXXXXXX = DELETE FROM table1
というように、DELETE文実行時にエラーになっている模様。

MySQL+Senna(Tritonn)の全文検索を使っているのですが、下記のバージョンで修正された
「条件無しdeleteを実行するとインデックスのフラグ情報が欠けてしまう問題」というのが怪しそう。

http://qwik.jp/tritonn/ChangeLog.html#mysql-5_0_45-tritonn-1_0_7

MySQLのバージョンは変更できないので、条件なしDELETEにならない方法を考えることにしました。

エラーが発生しているのはユニットテストで、FULLTEXT INDEXを設定したテーブルに対する fixtureのロード中。
なので、test_helper.rbで fixtureロード中の DELETE文で WHERE句を追加するようにしてみました。


test/test_helper.rb
----
+class Fixtures < YAML::Omap
+  FULLTEXT_TABLES = ["table1"]
+  def delete_existing_fixtures
+    where = (FULLTEXT_TABLES.include?(@table_name)) ? "WHERE id>0" : ""
+    @connection.delete "DELETE FROM #{@table_name} #{where}", 'Fixture Delete'
+  end
+end

ファイルの最後に追加すればOKです。

FULLTEXT_TABLESに FULLTEXT INDEXを設定してあるテーブルを追加すれば、DELETE文に「WHERE id>0」を挿入します。
idフィールドがない(Railsで作ったテーブルなら通常はありますが)場合は、ここでテーブル毎の SQLを作るようにします。
(ちなみに「WHERE 1=1」みたいなのはダメみたい)

これでユニットテストのエラーが発生しなくなりました♪(^^)v

2008年02月28日

[Trac] チケットを階層化したい。

こんにちわ。ばたっちです。

tracのチケット便利なんだけど、階層化できないのが不便。

TracMasterTicketsというプラグインがあるようですが、バージョン0.11以上で対応。
現在、インタアクト社提供の日本語版(0.10.4)を使っているのでダメなようです。。orz

redMineはこの辺の問題を最初から考慮して作られているみたいですね。


とりあえず、カスタムチケットで関連チケットへのリンクを追加して、レポートで関連の閲覧をできるようにしてみました。

まずは、ticket-customに関連チケットのフィールドを追加します。


trac.ini
----
[ticket-custom]
related_tickets = text
related_tickets.label = 関連チケット

追加したら Apache再起動して設定を反映させます。

チケット編集画面にて「チケット属性を変更する」に「関連チケット」の項目が追加されるので、「#999」のようにチケット番号を記入します。複数ある場合は半角スペースで区切って記入します。

次に新規レポートを作成します。SQLはこんなカンジ。


SELECT t.id AS ticket, t.summary,
       (CASE t.status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
       t.resolution,
       t.time AS created, t.changetime AS modified,
       r.value AS description
  FROM ticket t
       LEFT OUTER JOIN ticket_custom r ON (t.id = r.ticket AND r.name = 'related_tickets')
  WHERE t.status IN ('new', 'assigned', 'reopened', 'closed')
  ORDER BY t.id DESC

ticket_customを JOIN して、値(チケット番号)を「description」に AS して表示しています。

こうしておくと、一覧表示で関連チケットのチケット番号が Wikiフォーマット扱いになって、リンクにしてくれます。

あとは相互リンクにしたり、チケット編集画面で関連チケットへのリンクを表示したりできるといいんだけどなぁ。(^^;


さっそく追記:

編集画面でリンク表示は簡単にできそうなのでいじってみました。
tracのソースにある web_ui.pyというファイルを以下のように変更します。


/path/to/python/lib/python2.?/site-packages/trac/ticket/web_ui.py
----
--- web_ui.py.orig      2007-05-01 18:00:28.000000000 +0900
+++ web_ui.py   2008-02-28 12:57:06.000000000 +0900
@@ -600,9 +600,11 @@
                 field['skip'] = True
             req.hdf['ticket.fields.' + name] = field
 
+        relation = "\n\nrelated " + ticket.values.get('related_tickets')
+
         req.hdf['ticket.reporter_id'] = reporter_id
         req.hdf['ticket.description.formatted'] = wiki_to_html(
-            ticket['description'], self.env, req, db)
+            ticket['description'] + relation, self.env, req, db)
 
         req.hdf['ticket.opened'] = format_datetime(ticket.time_created)
         req.hdf['ticket.opened_delta'] = pretty_timedelta(ticket.time_created)

Apache再起動すれば、チケット編集画面の「チケットの概要」に「related #999」のようにリンクが出るようになりました。

かなりやっつけ(しかもPython素人)ですが、できたのでまあいいか。A^^;

2008年02月13日

[Ruby][Rails] CGI.escapeとURI.escape。

こんにちわ。ばたっちです。

WikiのようにURLに日本語のエスケープを使いたいと思いまして。。
CGI.escapeを使っていたのですが、他にも URI.escapeというのがありました。

URI - Rubyリファレンスマニュアル
http://www.ruby-lang.org/ja/man/html/URI.html

CGI - Rubyリファレンスマニュアル
http://www.ruby-lang.org/ja/man/html/cgi.html

若干、振る舞いが違うようで、たとえば CGI.escapeでは半角スペースが「+」に
変換されてしまうのですが、URI.escapeだと「%20」に変換してくれます。

ちなみに、Railsの link_toでも半角スペースは「%20」に変換されてますね。


ちょっと比較してみました。
URI.escapeでは、さらに第二引数でエスケープしない文字列を正規表現で指定できるようですね。

「aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>」という文字列を変換すると、以下のようになりました。


CGI.escape(str)
=> aA1%E3%81%82%E5%AE%89+%5E-_.%21%7E%2A%27%28%29%3B%2F%3F%3A%40%26%3D%2B%24%2C%5B%5D%22%23%25%7C%5C%7B%7D%3C%3E
URI.escape(str)
=> aA1%E3%81%82%E5%AE%89%20%5E-_.!~*'();/?:@&=+$,[]%22%23%25%7C%5C%7B%7D%3C%3E
URI.escape(str, /[^-_!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]/n) (*1)
=> aA1%E3%81%82%E5%AE%89%20%5E-_%2E!~*'();/?:@&=+$,[]%22%23%25%7C%5C%7B%7D%3C%3E
url_for (Rails)
=> aA1%E3%81%82%E5%AE%89%20%5E-_.!~*'();%2F%3F:@&amp;=+$,%5B%5D%22%23%25%7C%7B%7D%3C%3E

3つ目のエスケープパターンは、デフォルトのURI::UNSAFEから「.」を除去した場合です。


さらに、unescapeで逆変換した場合の結果。
(cescは CGI.escape、uescは URI.escape、mescは URI.escape(str, pattern)でそれぞれエスケープした文字列)


CGI.unescape(cesc)
=> aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>
CGI.unescape(uesc)
=> aA1あ安 ^-_.!~*'();/?:@&= $,[]"#%|\{}<>
CGI.unescape(mesc)
=> aA1あ安 ^-_.!~*'();/?:@&= $,[]"#%|\{}<>
URI.unescape(cesc)
=> aA1あ安+^-_.!~*'();/?:@&=+$,[]"#%|\{}<>
URI.unescape(uesc)
=> aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>
URI.unescape(mesc)
=> aA1あ安 ^-_.!~*'();/?:@&=+$,[]"#%|\{}<>

URI.escapeで変換したものは、URI.unescapeで変換しないと「+」が半角スペースに変換されてしまいます。

Railsの URLに「+」があった場合は半角スペースには直してくれないので、URI.unescapeに近い動きのようですね。

2008年01月24日

[MySQL][Rails] MySQL+Sennaの全文検索でスコア順にソートする。

こんにちわ。ばたっちです。

MySQL+Sennaな環境の全文検索について覚書。

  • 日本語でAND検索する→BOOLEAN MODEかつ「*D+」を付与
  • BOOLEAN MODEだとスコア順にならない→match() against()がスコアを返す

それぞれ反映したら SQLはこんなカンジになります。


SELECT *, match(text) against('*D+ 単語1 単語2' in boolean mode) AS score
  FROM table1s
 WHERE match(text) against('*D+ 単語1 単語2' in boolean mode)
 ORDER BY score DESC;

無理やり Railsにからめて(^^;、ActiveRecordではこんなカンジ。


match = "match(text) against('*D+ #{terms.join(' ')}' in boolean mode)
results = Table1.find(:all, :select => "*, #{match} AS score",
                      :conditions => match, :order => "score DESC")

これで BOOLEAN MODEでもマッチ率順になるので、LIMITで上位件数の絞込みできますね。φ(.. )

[Rails] SQLiteアダプタのtime型のマッピング修正。

こんにちわ。ばたっちです。

ついでに、ActiveRecord の SQLiteアダプタの修正です。
time型のマッピングが datetimeになってたので。。


module ActiveRecord
  module ConnectionAdapters #:nodoc:
    class SQLiteAdapter < AbstractAdapter
      def native_database_types #:nodoc:
        {
          :primary_key => default_primary_key_type,
          :string      => { :name => "varchar", :limit => 255 },
          :text        => { :name => "text" },
          :integer     => { :name => "integer" },
          :float       => { :name => "float" },
          :decimal     => { :name => "decimal" },
          :datetime    => { :name => "datetime" },
          :timestamp   => { :name => "datetime" },
-         :time        => { :name => "datetime" },
+         :time        => { :name => "time" },
          :date        => { :name => "date" },
          :binary      => { :name => "blob" },
          :boolean     => { :name => "boolean" }
        }
      end
    end
  end
end

「HTTPレスポンスのヘッダ折りたたみ。」の同じく、lib/ 以下に上記のファイルを配置して、config/environment.rb読み込みます。

以前、MySQLアダプタでも同様の間違いがあったように思う(今は直ってる)ので、いつかは修正されるかと。。

[Ruby][Rails] ログ出力フォーマットを変えたい!

こんにちわ。ばたっちです。

Rails標準のLoggerは、ログ出力フォーマットを簡単にいじれないっていうけど、ホント簡単にはできない。。orz

以下の方法でできたので覚書。もっといい方法があるだろうけど。

  • active_support の clean_logger.rb を lib/ 以下にコピー。
    (標準 Logger には独自の Formatter を設定できるんだけどバグってるぽくて、 その辺の修正とかされているみたい)
  • lib/以下に Formatter の拡張クラスを作る。
    
    class MyFormatter < Logger::Formatter
      Format = "[%s] %s:%s: %s\n"
      def call(severity, time, progname, msg)
        Format % [format_datetime(time), severity, progname, msg2str(msg)]
      end
      private
        def format_datetime(time)
          time.strftime("%Y-%m-%d %H:%M:%S.") << "%06d" % time.usec
        end
    end
    ----
    こんなログイメージ。
    =>[2008-01-24 00:00:00.000000] INFO:user/login: ログインしたす。
    
  • config/environment.rb で RAILS_DEFAULT_LOGGER に Formatter を設定。
    
    RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
    RAILS_DEFAULT_LOGGER.formatter = MyFormatter.new
    

ちょっと面倒だけど、なんでもできてしまうものですね。(^^)v

2007年12月27日

[Ruby][Rails] HTTPレスポンスのヘッダ折りたたみ。

こんにちわ。ばたっちです。

net/http使ってHTTPのレスポンスの処理をしていたら、ヘッダのパースでエラーになってるっぽい。


Net::HTTPBadResponse: wrong header line format
    /usr/lib/ruby/1.8/net/http.rb:2034:in `each_response_header'
    /usr/lib/ruby/1.8/net/http.rb:2008:in `read_new'

net/http.rbがHTTPヘッダの折りたたみ表記に対応してないみたいね。


Content-Type: text/html;
              charset=UTF-8

こういうの。確かRFC的には問題なかったと思うのだけど。(間違ってたらすみません)

というわけで以下のように修正。
/usr/lib/ruby/1.8/net/http.rbを直接置き換えてるんだけど、Railsプロジェクト内で上書きさせる方法ってないのかなぁ。(lib/以下に置いてみたけどダメでした)


--- http.rb.orig        2006-07-26 22:27:18.000000000 +0900
+++ http.rb     2007-11-22 12:58:28.000000000 +0900
@@ -2027,12 +2027,20 @@
       end
 
       def each_response_header(sock)
+        pm = ["", ""]
         while true
           line = sock.readuntil("\n", true).sub(/\s+\z/, '')
           break if line.empty?
-          m = /\A([^:]+):\s*/.match(line) or
-              raise HTTPBadResponse, 'wrong header line format'
-          yield m[1], m.post_match
+          m = /\A([^:]+):\s*/.match(line)
+          if m.nil?
+            pm[1] += line
+            next
+          end
+          yield pm[0], pm[1]
+          pm = [m[1], m.post_match]
         end
       end
     end

いちおうちゃんと動いています。(無保証)


追記:environment.rbの最後でrequireしとけばいいみたい。


lib/http_fix.rb
----
module Net   #:nodoc:
  class HTTPResponse
    class << HTTPResponse
      def each_response_header(sock)
        pm = ["", ""]
        while true
          line = sock.readuntil("\n", true).sub(/\s+\z/, '')
          break if line.empty?
          m = /\A([^:]+):\s*/.match(line)
          if m.nil?
            pm[1] += line
            next
          end
          yield pm[0], pm[1]
          pm = [m[1], m.post_match]
        end
      end
    end
  end   # HTTPResponse
end   # module Net

ってファイル作って、config/environment.rbの最後に、以下の行を追加すると。。φ(.. )


require 'http_fix.rb

2007年12月19日

[Rails] SymbolとStringで悩む。

こんにちわ。ばたっちです。

Rails って Symbol と String(文字列)の区別がなく使えるのかと思いきや、ActiveRecordのオブジェクトなどで record[:name]でも record["name"]でも参照できるのは、ActiveRecordクラスでラップしてるからのようで。

Symbolで参照できたり、文字列じゃないといけなかったり変だなーと思ってたら、ActiveRecordで SQLによる検索に connection.select_all(sql)を使ってたからでした。。orz

Rails は全体的に Symbolで統一しようとしている雰囲気なので、ここはなるべく Symbolで参照したいところ。

select_all(sql)の結果は単なるハッシュの配列ですが、find_by_sql(sql)を使うとActiveRecordオブジェクトの配列になります。


class Name < ActiveRecord::Base
end

※connection.select_all の結果はハッシュの配列。
Name.connection.select_all("SELECT * FROM names LIMIT 1")
=> [{"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}]

※find_by_sql の結果はActiveRecordの配列。
Name.find_by_sql("SELECT * FROM search_logs LIMIT 1")
=> [#<Name:0x99999999 @attributes={"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}>]

※find_by_sql で任意の結果も取れる。@errorsがあるけど参照は問題なさそう。
Name.find_by_sql("SELECT name, substring(created_at, 1, 10) day FROM names LIMIT 1")
=> [#<Name:0x99999999 @attributes={"day"=>"2007-12-19", "name"=>"名前1"},
           @errors=#<ActiveRecord::Errors:0x99999999 @base=#<Name:0x99999999 ...>, @errors={}>>]

※find の結果はActiveRecord。
Name.find(:first)
=> #<Name:0x99999999 @attributes={"name"=>"名前1", "created_at"=>"2007-12-19 12:00:00"}>

find_by_sqlで任意のカラムの結果が取れるとは知らなかった。

@errorsがあるけど、ちゃんと参照はできます。


result[:name]
=> "名前1"

result["name"]
=> "名前1"

@errorsが気持ち悪かったら connection.select_all の結果ハッシュのキーをSymbol変換するかなぁ。


def to_symhash(hash)
 result = {}
 hash.each_key {|k| result[k.to_sym] = hash[k] }
 result
end

results = Name.connection.select_all("SELECT * FROM names LIMIT 1")
results.collect{|r| to_symhash(r) }
=>[{:created_at=>"2007-12-19 12:00:00", :name=>"名前1"}]

2007年12月17日

[Trac][SVN] Trac+SVNな環境構築。

こんにちわ。ばたっちです。

いまさらですが Trac+SVNな環境を構築することがあったので覚書。

うわさには聞いていたけど、やたらいろんなものを入れなきゃいけないのですね。。

ちなみにパッケージの依存関係とか面倒なので、ここは硬派に(?)ソースからコンパイルで。

今回インストールしたものは以下のとおり。

  • httpd-2.2.6
  • swig-1.3.33
  • neon-0.25.5
  • subversion-1.4.5
  • Python-2.5.1
  • mod_python-3.3.1
  • sqlite-3.5.3
  • pysqlite-2.4.0
  • Genshi-0.4.4
  • clearsilver-0.10.4
  • trac-0.10.4-ja-1

これだけ入れて、最後にやっと Tracのインストール。。

インストールは以下のように /optに入れるので、適宜読み替えて下さい。


/opt/
 apache22/
 clearsilver/
 neon/
 python25/
 sqlite3/
 svn14/
 swig/
 svnroot/
 tracroot/

では、行きましょう♪


まずは、Subversionの環境構築からです。

[Apache]

wget http://ftp.kddilabs.jp/infosystems/apache/httpd/httpd-2.2.6.tar.bz2
tar jxvf httpd-2.2.6.tar.bz2
cd httpd-2.2.6/
./configure --prefix=/opt/apache22 \
      --enable-modules="so rewrite dav" \
      --enable-proxy --enable-proxy-ajp
make
sudo make install

※apacheアカウント作っとく。
chown -R apache.apache /opt/apache22/

[Python]

wget http://www.python.org/ftp/python/2.5.1/Python-2.5.1.tar.bz2
tar jxvf Python-2.5.1.tar.bz2
cd Python-2.5.1/
./configure --prefix=/opt/python25
make
sudo make install

[SWIG] (SubversionとPythonの連携に使うらしい)

wget http://jaist.dl.sourceforge.net/sourceforge/swig/swig-1.3.33.tar.gz
tar zxvf swig-1.3.33.tar.gz
cd swig-1.3.33/
./configure --prefix=/opt/swig \
      --with-python=/opt/python25/bin/python \
      --without-tcl
make
sudo make install

[neon] (SubversionでURIスキームを使う。0.25.5必須)

wget http://www.webdav.org/neon/neon-0.25.5.tar.gz
tar xvzf neon-0.25.5.tar.gz
cd neon-0.25.5/
./configure --prefix=/opt/local/neon
make
sudo make install

[Subversion]

tar jxvf subversion-1.4.5.tar.bz2
cd subversion-1.4.5/
env PYTHON=/opt/python25/bin/python \
./configure --prefix=/opt/svn14 \
      --with-apxs=/opt/apache22/bin/apxs \
      --with-apr=/opt/apache22/bin/apr-1-config \
      --with-apr-util=/opt/apache22/bin/apu-1-config \
      --enable-swig-bindings=python \
      --with-swig=/opt/swig/bin/swig \
      --with-neon=/opt/neon \
      --disable-static

※Makefileの設定が足りないので手で追加。
vi Makefile
----
-SVN_APR_LIBS = /opt/local/apache22/lib/libapr-0.la -lm -lcrypt
+SVN_APR_LIBS = /opt/local/apache22/lib/libapr-0.la -lm -lcrypt -lgssapi `krb5-config --libs` `xml2-config --libs`
-SVN_APR_INCLUDES = -I/opt/local/apache22/include
+SVN_APR_INCLUDES = -I/opt/local/apache22/include `krb5-config --cflags` `xml2-config --cflags`
----

make
sudo make install
make swig-py
make check-swig-py
sudo make install-swig-py

※Python連携のモジュールへのリンクを作成
cd /opt/python25/lib/python2.5/site-packages
sudo ln -s /opt/svn14/lib/svn-python .
sudo ln -s /opt/svn14/lib/svn-python/* .


ここまでインストールしたら、ひとまず Subversionの環境設定を行います。

まずは、リポジトリの作成。/opt/svnroot に置くようにしました。
リポジトリ作成後に定番のディレクトリを作成します。

svnadmin create /opt/svnroot/test
svn mkdir file:///opt/svnroot/test/trunk \
     file:///opt/svnroot/test/tags \
     file:///opt/svnroot/test/branches \
     -m "make trunk, tags, branches"

できたら、Apacheのモジュール設定。

デフォルトでは conf/extra/ ディレクトリ以下に各モジュール用の設定ファイルを置いて、conf/httpd.conf から読み込むようになっているようです。

既存の conf/extra/ を conf/extra-all/ にし、conf/extra/ 以下に必要なモジュールのみリンクを張るようにしてみました。この辺はお好みで。


conf/httpd.conf
----
-User daemon
-Group daemon
+User apache
+Group apache

+Include conf/extra/*.conf ※ファイルの末尾辺りに。
----

conf/extra/ の構成を変更して、Subversionの設定ファイルを追加する。


mv extra extra-all
mkdir extra

vi conf/extra-all/httpd-svn.conf
----
# cat /opt/apache22/conf/extra/httpd-svn.conf
# Subversion Repository

#LoadModule dav_svn_module modules/mod_dav_svn.so
#LoadModule authz_svn_module modules/mod_authz_svn.so

<Location /svn>
  DAV svn
  SVNParentPath /opt/svnroot

  AuthType Basic
  AuthName "Subversion Authentication Realm"
  AuthUserFile /opt/svnroot/.htpasswd
  AuthGroupFile /opt/svnroot/.htgroup

  # Limit write permission to list of valid users.
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require group svn_commiters
  </LimitExcept>

  <Limit GET PROPFIND OPTIONS REPORT>
    Require group svn_commiters
    Require group svn_readers
  </Limit>
</Location>
----

cd extra/
ln -s ../extra-all/httpd-default.conf .
ln -s ../extra-all/httpd-dav.conf .
ln -s ../extra-all/httpd-svn.conf .

リポジトリにアクセス制限用のファイルを作成します。


cd /opt/svnroot/

/opt/apache22/bin/htpasswd -c /opt/svnroot/.htpasswd user1 ※新規
/opt/apache22/bin/htpasswd /opt/svnroot/.htpasswd user2 ※追加

vi .htgroup
----
svn_commiters: user1
svn_readers: user1 user2
----

※Apacheから書き込みできるようにオーナーを変更
chown -R apache.apache test/

設定が完了したら、Apacheの起動確認です。

/opt/apache22/bin/apachectl を /etc/init.d にコピーするなりして、自動起動の設定などを行います。
(今回は自動起動にしていません。)


cd /etc/init.d/
ln -s /opt/apache22/bin/apachectl apache22

※起動
/etc/init.d/apache22 configtest
/etc/init.d/apache22 start

問題なく起動できたら、http://xxx.xxx.xxx.xxx/svn/test/ へアクセスしてリポジトリが見えたら成功です♪


続いて、Tracの環境構築。ここからが長い。。

必要なものをひたすらインストールしていきます。

[mod_python]

wget http://ftp.riken.jp/net/apache/httpd/modpython/mod_python-3.3.1.tgz
tar zxvf mod_python-3.3.1.tgz
cd mod_python-3.3.1/
./configure --with-apxs=/opt/apache22/bin/apxs \
      --with-python=/opt/python25/bin/python
make
sudo make install

[SQLite3]

※今回はデフォルトでDBはSQLite3に。PostgreSQLでもできるらしい。MySQLはまだお試し版の模様。
wget http://www.sqlite.org/sqlite-3.5.3.tar.gz
tar zxvf sqlite-3.5.3.tar.gz
cd sqlite-3.5.3/
./configure --prefix=/opt/sqlite3 --enable-threadsafe --disable-tcl
make
sudo make install

[pysqlite]

wget http://initd.org/pub/software/pysqlite/releases/2.4/2.4.0/pysqlite-2.4.0.tar.gz
tar zxvf pysqlite-2.4.0.tar.gz
cd pysqlite-2.4.0/

※参照するSQLiteのパスなどを設定
vi setup.cfg
----
 [build_ext]
 define=
 include_dirs=/opt/sqlite3/include
 library_dirs=/opt/sqlite3/lib
+ rpath=/opt/sqlite3/lib ※これ追加
 libraries=sqlite3
----

/opt/python25/bin/python setup.py build

※sqlite用のextensionが、libsqlite3.soを参照できるか確認
ldd build/lib.linux-i686-2.5/pysqlite2/_sqlite.so
    libsqlite3.so.0 => /opt/sqlite3/lib/libsqlite3.so.0 (0x008e4000)
    libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00775000)
    libc.so.6 => /lib/tls/libc.so.6 (0x00b0a000)
    /lib/ld-linux.so.2 (0x00489000)

sudo /opt/python25/bin/python setup.py install

※正常に動作するか確認
/opt/python25/bin/python
>>> from pysqlite2.test import test
>>> test()

[clearsilver]

wget http://www.clearsilver.net/downloads/clearsilver-0.10.4.tar.gz
tar zxvf clearsilver-0.10.4.tar.gz
cd clearsilver-0.10.4/
./configure --prefix=/opt/clearsilver \
      --with-apache=/opt/apache22 \
      --with-python=/opt/python25/bin/python
make
sudo make install

[Genshi]

wget http://ftp.edgewall.com/pub/genshi/Genshi-0.4.4.tar.bz2
tar jxvf Genshi-0.4.4.tar.bz2
cd Genshi-0.4.4/
sudo /opt/python25/bin/python setup.py install

[Trac] ※やっと!

wget http://www.i-act.co.jp/project/products/downloads/trac-0.10.4-ja-1.zip
unzip trac-0.10.4-ja-1.zip
sudo /opt/python25/bin/python setup.py install

ちなみに、pysqlite-2.4.0を使う場合に不具合があるようなので、修正しておきましょう。
(see. http://trac.edgewall.org/changeset/6223)


vi /opt/python25/lib/python2.5/site-packages/trac/db/sqlite_backend.py
----
         raise TracError('Database already exists at %s' % path)
       os.makedirs(os.path.split(path)[0])
+     if isinstance(path, unicode): # needed with 2.4.0
+       path = path.encode('utf-8')
     cnx = sqlite.connect(path, timeout=int(params.get('timeout', 10000)))
     cursor = cnx.cursor()
- - -
       self._active_cursors = weakref.WeakKeyDictionary()
       timeout = int(params.get('timeout', 10.0))
+       if isinstance(path, unicode): # needed with 2.4.0
+         path = path.encode('utf-8')
       cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES,
                  check_same_thread=sqlite_version < 30301,
----


では、これから Tracの環境設定をしていきます。

まずは、リポジトリの作成。/opt/tracroot に作成することにします。


/opt/python25/bin/trac-admin /opt/tracroot/test initenv

※以下の質問に答えていく。
Project Name [My Project]> test
Database connection string [sqlite:db/trac.db]>
Repository type [svn]>
Path to repository [/path/to/repos]> /opt/svnroot/test
Templates directory [/opt/python25/share/trac/templates]>

※リポジトリの文字コード設定を変更しておく。今回は UTF-8
vi /opt/tracroot/test/conf/trac.ini
----
-default_charset = iso-8859-15
+default_charset = utf-8
----

Trac のテスト用サーバを起動して、ブラウザで表示できれば成功です♪


/opt/python25/bin/tracd --port=8000 /opt/tracroot/test

※http://xxx.xxx.xxx.xxx:8000/test/ へアクセス


Trac 単体で動いたら Apache経由の設定を行います。


cd /opt/apache22/conf/

※mod_pythonの設定ファイル作成
vi extra-all/httpd-python.conf
----
LoadModule python_module modules/mod_python.so
----

※Tracの設定ファイル作成
vi extra-all/httpd-trac.conf
----
<Location /trac>
  SetHandler mod_python
  PythonDebug On
  PythonHandler trac.web.modpython_frontend
  PythonOption TracEnvParentDir /opt/tracroot
  PythonOption TracUriRoot /trac
</Location>

<LocationMatch "/trac/.*">
  AuthType Basic
  AuthName "trac"
  AuthUserFile "/opt/tracroot/.htpasswd"
  Require valid-user
</LocationMatch>
----

cd extra/
ln -s ../extra-all/httpd-python.conf .
ln -s ../extra-all/httpd-trac.conf .

Apache から Trac のリポジトリにアクセスできるようにします。


※オーナーを変更
chwon -R apache.apache /opt/tracroot/test/

※アクセス制限のファイル作成
/opt/apache22/bin/htpasswd -c /opt/tracroot/.htpasswd user1

設定ができたら Apacheを再起動します。


/etc/init.d/apache22 configtest
/etc/init.d/apache22 restart

ブラウザで http://xxx.xxx.xxx.xxx/trac/test/ を開いて、Tracの画面が表示できたら成功です♪

Subversion のリポジトリも表示できることを確認しましょう。


以上。お疲れ様でした。A^^;


追記:neon追加

2007年08月14日

キャリアの方向と技術選択

暫くご無沙汰しておりました、岡部です。暑中お見舞い申し上げます。 連日真夏日やら猛暑日やらで、 ようやく夏が来たものの、亜熱帯に変化しているような厳しい暑さですね。 食欲がなくても良く食べよく眠って乗り切りましょう。 あぁそれと水分補給も忘れずに。

今回は少し遠くを見渡す話です。

技術者のキャリアパスは(特に日本の多くの場合では)限られているのは事実であると思います。 私自身は「創ってナンボ役立ってナンボ」ですから、希望を言えばかなり特殊なきゃアリアパスに ならざるを得ませんが、現実に実践実行していける中期目標を想像しながら悪戦苦闘しています。

話を膨らませすぎると収拾がつかないので、技術者の技術選択が(マネジメント等ではなく) 技術的なキャリアパスに影響するという視点から、 更に絞った話題としてプログラミング言語にスポットを当ててみようと思います。

一口に言語といってもピンからキリまで、 その言語の高級度*1の 幅があると思います。 上は皆さんもよく知っているような数種類の言語と「マクロ」類、下は手書きのCとか(++も無しね^^;) アセンブラといった感じでしょうか。シェルプログラミングとかPC-98のROM-BASICなんかはどの変になるでしょうね・・・

キャリア選択は十人十色千差万別と思いますが、 上記の流れで私ならどうだろうか、考えてみます。

私は各論の上で、工程の最初から最後まで例えば基幹業務システムの受注であれば、 受注のところから相手を観察してその語の話題作りをし、要求を整理し、アーキテクチャの選別と設計、 UI設計、システムの設計、アジャイルコーディングとテスト、導入準備と顧客教育、 試験作動と顧客側担当者の理解度向上、本番作動、トラブル対応、 時間と共に変化する要求へのアジャイル対応、etc.全工程をある程度は理解し手伝いに参加できる状態を 維持するように心がけています。

そうすると、時間も労力も限られているので、全体的に浅い能力と経験 ということになりますから、主力たる技術の選択が必要になってきます。 *2

私の場合であれば、カードは・・・
ハードウェア・ハードプラットフォーム
PC自作・サーバ構築・ネットワークアーキテクト及び管理運用
ソフトウェアプラットフォーム
OS
Windows3.1からXPまで(ME除く/残念ながらNT時代のはちょっと不足)、 MS-DOS5~、RedHatLinux7.3~(+Fedora)
OS設定類のカスタマイズ
ネットワーク・DB関連
PostgreSQL、Oracle、BIND、qmail、他多数の(特にネットワーク関連の) フリーないしはオープンソースの方々
言語
C(C++)(LSIC/Borland/Turbo/GCC)、VisualC++(6)
(N88)BASIC、Windows用BASICエミュレータ、VisualBasic++(6)
Java(新人研修で独習Javaを内職してました^^;) エクリプス環境と最近のバージョンも使えないこともないということが、 とある弊社の開発案件で判りましたが、ちょっと厳しいかな? それ以前に仕事でJavaは一度も触れていませんでしたから。 *3
シェルスクリプト(Win-DOS、/bin/sh)
駆使できると快感^^; *4
Perl、PHP
キリがないので省略(ぇ
まぁどんな言語でもリファレンスさえあれば慣れだけですし、 暫く使っていない言語も然りですし。 自分の側の問題は各言語ではなくて根底を 理解してるかどうかだけのことと思います。
規模・スタイル
一人から数十人まで。
ガチガチのウォーターフォールからアジャイルまで。 「パターン」などは知らずに使っていたことを後から気付いたり。
基幹業務システム開発のテクニカルアドバイザーから、 ちょっとしたツールの作成(VBでシビアな通信とサービス化なんかもやりました) やデータ加工バッチまで。
WebもHTML(これはDTDも原文で読みました/未だに手書き)、JavaScript、 Flash*5・ 更には画像やアイコンの調達または作成まで。
偏屈な分、付き合いにくいと相手が思うかも?(^^;

棚卸はたまには良いですが、晒してしまうとさすがに恥ずかしいですね。

しかし私は今のところ、手持ちのカードから次のような主力を構想しています。
  • Perl5を中心とした軽量なアジャイル手法。
    Perl5の選択:CUI・CGI(・そして実はGUIや音も!)
    軽量なスクリプト言語の中で、 メジャー且つ 安定していることから。
    数年前の話なので正しくはないかもしれませんが、 PHP(Ver4後半)は高機能新機能の為に多くの安定性を欠いていました。 なにしろマイナーバージョンがちょっと挙がるだけで関数の仕様すら簡単に 変更(修正)されてしまうので、ベンダーツリーを用意して、都度マージを しなくてはいけないということを経験しています。その頃は日本のPHPユーザ 及び開発陣のMLを常時気にしながら、解説を加えたり要望を出したりしていました。
    しかしそんな監視を開発中ずっと気にかけているなんて可笑しいでしょう? たった1ヶ月の開発だとしても(その後の運用も考えますが)、 とても軽量とはいえなくなります。言語は軽量でも開発者には重量です。
    Perl5はほぼどんなところでも存在していて すぐに動作させてみることが出来ます。 (既存サーバへのインストールや設定の変更が出来ない顧客も結構います。) シェルスクリプトも同様ですし、そして併用しますが。
    枯れている技術は重要な使用上の変更が加えられてしまうリスクも小さなものです。
  • Windowsアプリケーションを作成する手立て
    やっぱり一つは欲しいですね、自作方法を。
    どうやったとしてもWindowsが駆逐されるということは、 今のところ考えられないでしょう。
    私の過去経験から導かれる「楽な」方法は、 VB6+VC++6のDLL+他のDLL+WindowsAPI (場合によってはアプリケーションサーバとシンクライアントの組み合わせ(仮想含む))。
    しかし今後を見据えた場合、 やはり.NETを選択する必要性が強まるでしょう。 顧客のイメージ等も鑑みなくてはなりませんし、 また、実際には旧来のVer6世代でも大抵は困りはしなくても、 いざ乗り換えるとした時には多分大きな仕様変更があるでしょうから、 予め手は用意しておいたほうが良いと考えています。
  • モデリング・アドバイザー(コンサル含む)(長期計画^^;)

プログラマ」が窮屈な今の日本に在っても、 一度立ち止まって、深呼吸し、棚卸と戦略練りをしてみては如何でしょうか?

戦術を練ったり実戦に出るのは、それからでも遅くはないし、十分な準備が出来るでしょう。 自分と競合他社の強み弱みを書き出して議論する方法があったと思いますが、そういうことです。

ちなみに、上記の狙い目の構成例で私がJavaにもRubyにも触れなかったのにも、 ちゃんと理由があります。Javaはいくらでも技術者が居るので、 必要な時に使えれば十分(「必要な時に必要なだけ」)。 Rubyは誕生した頃から頭の隅に置いていましたが、当時は学生で 空き時間や内職中にCやらCMMやらを読むのに忙しく、 結局未だに触ったことがないからです。 また、最近はRoRで既に盛り上がってますから、 こちらも必要なときに必要なだけ用意することにしようと考えています。

要するに、私のキャリアプランはユーティリティ性や適応力や応用力を 関連する全ての分野で最低ラインを維持しながら、 代えの効かない仕事を狙う、といったところでしょうか。

私事の晒しになってしまいましたが、如何でしたでしょうか。 キャリアプランをふと考えてみたり、 技術者が深呼吸できる時間になってくれれば嬉しい限りです。

*1
低級言語とか高級言語と呼ぶのはちょっと気に入らないですね。 せめて下層上層とか。。。
*2
幅広い知識と経験はユーティリティに優れ、広い視野を与えてくれる、一つの解だとは思います。
*3
仕事らしい仕事でJavaに全く触れずに来たものの、社会人1年目の最初の仕事が Web上でPDFを作成するようなソリューションの比較評価だったので、 当時のApache+Javaでサーブレットを作って見た事は在ります。(新人研修時の内職正解(^^;)
弊社入社時にはCUIのJava(まるでCの移植^^;)で課題を提出しましたし、一応。
*4
シェルスクリプトだけで、昔ならCでガリガリ欠かなくてはならないような一連のシステムを 作った実績があります。
*5
特に見栄えの方ではなく、例えば綺麗なUIコンポーネントが一枚のHTMLに個別に存在しても連動して動くなど、 オブジェクティブでコンポーネントなHTTPリッチクライアントを提供できると踏んで実験したことがあります。 それなりの成果は在りましたが、Flashが使える人はデザイナで、プログラム書く人は興味を向けないなど、 即投入できる環境がなかったので、それ以来保留したままですが。 (JavaScriptの駆使でかなりのことが出来ますしね・・・)
岡部 太一
テクニカルデプト システムエンジニア

2007年07月12日

トップ10デッドコンピュータスキル

dead computer skillsすなわち、使われなくなったコンピュータスキルという記事を見つけた。

The top 10 dead (or dying) computer skills

http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9020942&pageNumber=1

面白いので、項目だけ引用してみる。

1. Cobol
2. Nonrelational DBMS
3. Non-IP networks
4. cc:Mail
5. ColdFusion
6. C programming
7. PowerBuilder
8. Certified NetWare Engineers
9. PC network administrators
10. OS/2

確かにというものもあるけど、笑えないのもあったりする。
これに対して、Noといえないコンピュータスキルという記事もあるが、こちらはあまり面白くない。
http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9026623&pageNumber=1

それよりも、ホットスキル/コールドスキルの方が面白い。
http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=112360&pageNumber=1

ホット
Enterprise architecture
Project leadership
Business process re-engineering
Project planning, budgeting and scheduling
Third-party provider managers
Systems analysis
Systems design
Network design
Systems auditing
コールド
Programming
Routine coding
Systems testing
Support and help desk
Operations -- server hosting, telecommunications, operating systems

コールドはオフショアに移行して行くんだろうけど、プログラミングがあるのは残念だったりする。

長瀬

2007年04月19日

[Rails][XP] RadRails+XPairtiseでペアプロ♪

こんにちわ。ばたっちです。

最近、社内のシステムのメンテナンスをしています。(メルマガ配信システムもそうですが)
ユーザが近くにいるので、すぐに声を聴くことができて、フィードバックの効果を感じることができますね。

昔からこういう作業することが多かったけど、もしかしたら向いてるのかな?(^^;


Eclipse 上でペアプロができるというプラグインがあったので、試してみました。
こんなやつです↓

XPairtise - http://xpairtise.sourceforge.net/

「エックスペアタイズ」って読むのかな?

上記のサイトで、スクリーンショット付きで説明されているので分かりやすいのですが、面白いなと思ったのは、ドライバとナビゲータという役割付けがされて、エディタの閲覧を共有しつつ、編集はドライバのみが可能という切り分け方をしています。

画面を共有するというのは聞くけど、エディタを排他共有するのは新鮮な気がしました。
(他のツールは知らないのですが。。A^^;)
IDE として Eclipse を使うのであれば、選択肢としてはよさそうですよ。


今回は、ちょっと踏み込んで RadRailsXPairtise を試してみました。
XPairtise を試してみたカンジだと、とくに開発言語には依存してなさそうだったので。。(^^;

まずは、環境構築。
残念ながら、RCP版の RadRails だと、プラグインの追加ができなかった(できるかもしれないけど、方法が分からない。。)ので、プラグイン版の RadRailsを入れて共存させる方法にしてみました。

新規に Eclipse をインストールします。(説明は省略)

先に、RadRailsに必要なプラグインをインストールしてしまいましょう。
ファイルメニューから、[Help]→[Software Updates]→[Find and Install]を選択し、プラグインのインストーラ画面を開きます。

[Search for new features to install] を選んで次へ進み、[New Remote Site] でアップデートサイトを登録して、プラグインを入れます。
インストールするプラグインはこんなカンジ。

  RDT
  http://updatesite.rubypeople.org/release
  RadRails
  http://radrails.sourceforge.net/update
  Subclipse
  http://subclipse.tigris.org/update_1.0.x

RadRails の環境ができたら、次に XPairtiseのプラグインを入れます。
こちらは、ファイルをダウンロードして、圧縮ファイルを手動で展開する方法で。

ダウンロードサイトはこちら。
http://sourceforge.net/projects/xpairtise/

必要なファイルは以下の2つです。

de.fuh.xpairtise_plugin_1.0.1.zip
de.fuh.xpairtise_server_1.0.1.zip

プラグインの方は ZIPファイルを展開してできた JARファイルを、Eclipseの pluginフォルダにコピーして、Eclipse を再起動すれば OKです。


サーバの方は、クライアント(Eclipse)から接続する前に起動しておきましょう。
展開したファイル中の、runserver.batを実行すれば OK です。

ただし、サーバではユーザやセッションの情報を、XPairtiseUserDB.dtd/xml、XPairtiseSessionDB.dtd/xml というファイルを作って管理するようなのですが、以前に生成されたこれらのファイルが残っていると、次回の起動時にエラーになって起動できなくなってしまいました。

サーバのフォルダにある、これらの4つのファイルを削除してから、runserver.batを実行しましょう。(ユーザとか登録し直しだけど。。)


クライアント側は、パースペクティブの切替で「XPairtise」を選択してペアプロモードにします。

xpairtise1.jpg

最初にサーバへアカウントを登録する必要があるので、[Window]→[Preference]→[XPairtise]で設定画面を開いて[Create New Account]からアカウントを作成します。
アカウントを作成すると自動でサーバに接続され、[XP User Gallery]ビューに接続状態が表示されます。

xpairtise_pref.jpg
xpairtise_user.jpg

ペアプロを開始するには[XP Session Gallery]ビューを開いて、右クリックメニューの[Create]を選択して、セッションを作成します。

xpairtise_session.jpg

セッションを作成しただけでは、まだセッションに参加していることにはならないので[XP Session Gallery]ビューに表示されたセッションを右クリックして[Join]します。
2人目以降も[XP Session Gallery]ビューを右クリックし、[Join]でセッションに参加します。

2人以上セッションに参加すると、ペアプロが開始できるようになります。
先にセッションに参加した人が「ドライバ」になるみたいですね。
役割を入れ替えたいときは、ウィンドウ下の[Press to request a role change]ボタン(虫眼鏡みたいなやつ)で役割変更要求を相手に送り、相手が承諾したら変更になるようです。

xpairtise_drvnav.jpg

Ruby のコードでもちゃんとエディタを共有できていますね。

XPairtise はエディタの他にも、ホワイトボードやチャットなどの共有機能もあります。
VPNとかで接続された環境なら、遠隔でのペアプロもできますね♪

あとは、インターネット越しでも使えるのかな?(^^;

2007年04月03日

[Rails] RailsでSQLite♪

こんにちわ。ばたっちです。

年度変わっちゃいました(汗

メルマガ配信システムも開発が続くことになり、社内でもRailsが市民権を得てきたかな。
ユーザに喜んでもらえるシステムに育てていきたいですね♪

もう、忘れかけていたUSBメモリの続きw
前回は、SQLiteとRubyのモジュールをインストールしました。


あ、そうそう。
Windowsのバッチファイルでドライブ名を取る件は結局分からなかったので、
バッチの引数で指定できるようにしました。

chenv.bat
----
@echo off
set Drive=%1% ←ここ
set Path=%Drive%:\ruby\bin;%Path%
set Path=%Drive%:\sqlite3;%Path%
----

こうやって使います。

E:\> chenv.bat E


さて、それは置いといて。。
RailsでSQLiteを使うためには、database.ymlを変更するだけでOKです。

MySQLの場合はこんなカンジですが、

config/database.yml
----
development:
 adapter: mysql
 database: webnote_development
 username: root
 password: mysql
 host: localhost
 encoding: UTF8

SQLiteだとこんなカンジになります。

config/database.yml
----
development:
 adapter: sqlite3
 dbfile: db/webnote_development.db
 encoding: UTF8

ストレージがファイルになるので、database: ではなく、dbfile: というのを使うんですね。
dbfile: には、アプリケーションのトップディレクトリ(webnoteとか)からの相対パスを指定します。






「実践 Ruby on Rails Webプログラミング入門」

出版:株式会社ソーテック社

演習では、あらかじめmemopagesというテーブルを作って、scaffoldで雛形を生成しているので、
同じようにやってみましょう。

E:\> sqlite3.exe db\webnote_development.db
sqlite> create table memopages (
   ...>  id  int not null,
   ...>  title varchar(255) not null,
   ...>  content text,
   ...>  primary key (id)
   ...> );
sqlite> .schema
CREATE TABLE memopages (
 id  int not null,
 title varchar(255) not null,
 content text,
 primary key (id)
);
CREATE TABLE schema_info (version integer);

rakeでスキーマ定義のダンプを採ってみるとこんなカンジになりました。

E:\> rake db:schema:dump
 :
 create_table "memopages", :force => true do |t|
  t.column "title", :string, :default => "", :null => false
  t.column "content", :text, :default => ""
  t.column "updated_at", :datetime
 end

 add_index "memopages", ["id"], :name => "sqlite_autoindex_memopages_1", :unique => true
 :

scaffoldしたら、演習を参考にmigrate対応します。
migrateのテーブル生成スクリプトはこんなカンジ

class CreateMemoPage < ActiveRecord::Migration
 def self.up
  create_table :memopages do |t|
   t.column :title, :string, :null => false
   t.column :content, :text
   t.column :updated_at, :datetime
  end
 end

 def self.down
  drop_table :memopages
 end
end

migrateでテーブル作ると、スキーマのダンプから add_index 行がなくなるんですよね。
ま、いいか(いいのか?)

db\schema.db
----
 create_table "memopages", :force => true do |t|
  t.column "title", :string, :default => "", :null => false
  t.column "content", :text, :default => ""
  t.column "updated_at", :datetime
 end

ActiveRecord使えば、異なるデータベースに対応するのも簡単ですね♪
ちょっとした個人用途やプロジェクトで使うくらいのアプリケーションならSQLiteで十分そうだし。

2007年03月20日

気が利くかどうか

最近、システム開発成功の鍵は、
どれだけ「気が利くか」なのではないかと思っています。
気が利く人なら提案、要件定義、設計、開発、試験と
どのフェーズでも活躍できそうです。
気が利くからこそ、前もってさまざまなリスクを
つぶしておくこともできるのでしょうしね。
ただ、気が利く人ほど仕事は忙しくなっているような気も(^^;

              テクニカルデプト  橋本 大輔

2007年03月04日

未知への適応法

暫くご無沙汰しておりました、岡部です。まだ1年は経たないと思いますが、年月が過ぎるのは早いですね。

今回は、最近ふと思ったことを少しだけ、たまには「モデリング」カテゴリでも書いてみたいと思います。 前回の私の記事(科学と魔法)にも通じるところがあります。

私にはもうすぐ幼稚園に入る子供が居るのですが、子供の成長には目を見張るものがあります。 大人になってもこのくらい成長できたら、すごいだろうなとは、どの親も思うことでしょうか。

子供と接し、その成長を見守りながら、刺激を与えたり、たまには誘導したりしていると、 子供がどのように物事を理解し、本人にとっての世界観を構築していくか、その過程が見えてきます。

子供にとっては、世界は初めてみるものです。 (稀に特殊な才能を当初からもっている子供も居るかもしれませんが。) 初めてみる世界の構造や成り立ち・ルール・仕組み・因果・自分の行為の影響、 そういったことを一般的には試行錯誤しながら会得していくように見えます。

実際、ある程度成長するまでは、子供は試行錯誤し、 学習はその試行錯誤結果に影響を受けているように見えます。 例えば、それが実際には正しくなくても、ある一度の試行の結果でさえ次回に活かします。 勿論、試行回数が増えれば増えるほど、その次に正しい行動を取れる精度も向上します。

余談ですが、ですから親は、この時期にはある程度結果を導くなどして、 子供の成長する方向を誘導することが出来ます。悪用はいけませんよ! でも、それは通常「しつけ」に利用されます。 (「しつけ」とは、現社会のルールを教え、適用させ、生き抜く術を与える務めなり。)

しかし、ある程度試行錯誤によって成長すると、今度は「組み立て」を始めます。 試行錯誤で得られる知識は断片的なので、これを繋ぎ合わせて、体系付け始めるわけです。 そうすると「概念」が必要になってきます。 つまり、単なる事実の積み重ねではなく、それらを抽象化することが必要になります。

「数」、「時間」、そのもの自体とは別途に付与される「役割」とその名前など。 やたら数え始めたり、昼と夜の区別、「もうすぐ」「あとで」、時計、「ごっこ遊び」などが代表的でしょうか。

「科学と魔法」で言えば、数打ちゃ当たる魔法を連打したのち、その結果を科学的に分析し始めるのです。 科学とは「記号」と「帰納」と「演繹」であると、私は書きました。そしてそれは、「モデリング」です。

最初に結論を述べずにグダグダ言うのは私の悪い癖ですが、 最初に述べた「最近ふと思った」と述べたのは、そんな子供の「考え方」の変化と動きを見ていて、 『子供は常にリモデリングを繰り返しながら生きている』こと気付いたということです。

なんということでしょう!(ビフォーアフター風に!)
子供の驚異的な成長は、未知に適応する為の究極のアジャイルモデリングに支えられているのではないでしょか。

今回は、ここで終わりです。何か示唆が得られれば幸いです。

2007年02月19日

[Rails] 社内システム作ってみました♪

こんにちわ。ばたっちです。

気がつけばもう2月。
USBメモリの続きはしばしお待ちを。。(やってないんだろ?>自分)


今日は社内の勉強会(Rails)の話題。

書籍の演習を終えた後の題材として、弊社で発行しているメルマガの配信システムを作成しています。
先週末、最初のリリースだったのですが、無事配信できました。(パチパチ)
ちなみに、明日打ち上げ。うふっ(^^;


勉強会で何かシステムを作ってみようということで、題材を探していたのですが、ちょうどメルマガ発行担当の部門から配信システム作成の依頼があったので、これを作成することになりました。
やはり、ユーザが必要としてくれるものを作るのは作りがいもありますからね!
ユーザが同じ社内にいるので、オンサイト顧客にもなりますし♪

開発は最初のリリース期間が1ヶ月。

一週間毎のイテレーションで、週2回ペースで集まるようにしました。
勉強会だと、メンバはボランティアでの参加になるので、みんなが集まる場は、タスク分けなどの情報共有にあてるという形で進めました。
開発の実作業は残りの時間と、各自の空き時間で協力してもらいました。m(_ _)m

開発期間が短期なので、現在の業務(メルマガ配信)ができるように、最低限の開発スコープに抑えるのが大事ですね。
今後もユーザの声を聴きながら、少しずつ機能拡張していきたいと思います。
(作ってるといろいろアイデアが浮かぶんですが、それを抑えるのが大変ですw)


また、この開発を機に部門を越えた交流も活発になりました♪
食事会や、プレゼント交換会などイベントしたり。。(メルマガ担当者は女性なので、すごく喜んでもらいました)
部門が違うと、業務で関わりがないとなかなか話す機会がないので、こんなおまけの効果があるとうれしいですね。

開発を通じて、仲良くなれるなんて、技術者冥利につきません?(大げさw)

2006年12月15日

[Rails] DBもUSBメモリで。

こんにちわ。ばたっちです。

年末になると、なぜかバタバタしだしますよね。
気持ち的にも。なんだろ、あれ(^^;

Railsの勉強を始めたきっかけで、最近、実プロジェクト(Javaではない)でも Railsのアーキテクチャっぽい仕組みを作ってみたりしています。移植とまでいかないですが、実際に真似て作ってみるとよくできたフレームワークだなと感心しますねぇ。


さて、「Rails on USBメモリ」の続き。
勉強会では、下記書籍の演習をやっていて、同じ例題のアプリケーションをメモリ上にも作ってみます。


「実践 Ruby on Rails Webプログラミング入門」

出版:株式会社ソーテック社

演習では、DBに MySQLを使っていますが、これをポータブルにできるのか分からなかった(調べろ)ので、
「SQLite」というライブラリベースの DBを使ってみました。
(これステキ♪ こういうシンプルなDBが欲しかった)

まずは、SQLiteのダウンロードから。
http://www.sqlite.org/download.html

バージョンは 3.3.8というのが最新のようなので、以下の2つのファイルを取ってきます。

・sqlite-3_3_8.zip
・sqlitedll-3_3_8.zip

インストール場所は E:\sqlite3 とします。こんなカンジ。

E:\sqlite3
  sqlite3.exe
  sqlite3.def
  sqlite3.dll

インストールできたら、ちゃんと動くか試してみましょう。
引数に DBのファイル名を指定して、sqlite3.exe コマンドを実行するだけで、DBが使えるようになります。
ファイルが存在しない場合は、新しくファイルが作られます。

E:\> E:\sqlite3\sqlite3.exe test.db
SQLite version 3.3.8
Enter ".help" for instructions
sqlite>

SQLをファイルから入力する場合は、ちゃんと標準入力も使えるようです。
(Windowsでも標準入力って言うんですかね?)

E:\> E:\sqlite3\sqlite3.exe test.db < create_table_user.sql

SQLiteが動いたら、前回作った環境設定のバッチファイルに、SQLiteのコマンドパスも追加しときましょう。

chenv.bat
----
@echo off
set Drive=E
set Path=%Drive%:\ruby\bin;%Path%
set Path=%Drive%:\sqlite3;%Path%
----

※ちょっと改良。でも、やっぱりドライブ名を自動取得する方法は分からず。。


次に Railsに SQLiteのドライバをインストールします。
(SQLiteはデフォルトでは入っていないようです)
Rails同様、gemコマンドで簡単にインストールできます。

E:\> gem install sqlite3-ruby


長くなってきたので、今日はここまで A^^;
次回は、演習のアプリケーションを SQLiteを使って動かしてみましょう♪

2006年12月07日

新刊のご案内

弊社の社員が執筆に係わった書籍が
今月3冊ほど発売されますのでお知らせいたします。

SOAシステムモデリングハンドブック(翔泳社)
http://www.seshop.com/detail.asp?pid=7476

Railsレシピ(オライリー)
http://www.oreilly.co.jp/books/4873113121/

現場のUML(ソーテック社)
http://www.sotechsha.co.jp/pc/html/542.htm

            テクニカルデプト  橋本 大輔

2006年11月30日

[Rails] Rails on USBメモリってどぉ?

こんにちわ。ばたっちです。

最近、社内でRailsの勉強会始めました。

Rubyという「軽い」言語もそうですが、いろいろ「気のつく」機能が盛りだくさんで、これが本当の「フレームワーク」って感じています。
(ちまたに存在するフレームワークは、使うためのコストが高くついて、本来の作業を軽くするという効果からかけ離れているものばかりなのでw)

業務の開発では、Java+Struts/WebLogic のような一般的な Java環境ですが、早くも
「Javaはもういいよ。。」
って気持ちになってます。A^^;
まだ、1年くらいしか使ってないけど。Java


さて、勉強会ではノートPCを使っての演習をしてるのですが、PCの空きがなくなる(勉強会で占有できませんし。。)と困るなってことで、

「Rails on USBメモリ」

なんてのを実験してみました。(まだ実験中)
メモリ上に環境作っちゃえば、あとはどんなPC使っても、作業できるなと思って。(ポータビリティ万歳!)


まずは、メモリを用意。以下、Eドライブとします。

E:\ruby

に Ruby環境をインストール。既存の rubyフォルダをコピってもいけるかも。

今回、利用するのは Windows版の One-Click Installerです。
http://rubyforge.org/projects/rubyinstaller/

ダウンロードのリンクから、ruby185-21.exe を取得します。
インストーラを起動して、メニューに沿って進めるだけでインストール完了です。

E:\ruby\bin にパスを通しておきますが、OS の設定にしてしまうと、環境が変わるたびに設定が必要になるので、環境設定用のバッチを作っておきます。

chenv.bat (change environmentって意味です)
----
@echo off
set Path=E:\ruby\bin;%Path%
----

これで、メモリを挿して、コマンドプロンプトで実行すれば、Rubyが使えるようになります。

C:\> E:
E:\> .\chenv.bat

※現在いるドライブ名とかも自動で取れると完璧なんだけどな。
 だれか知ってたら教えて下さい。m(_ _)m

gem コマンド使って Railsをインストールすれば完了です。

E:\> gem install rails -y

試しに exampleプロジェクト作って、WEBrickの起動確認までしておきましょう。

E:\> mkdir study
E:\> cd study
E:\> rails example
E:\> cd example
E:\> ruby .\script\server

WEBrickが起動したら、http://localhost:3000/ にアクセスし、Railsの画面が表示されたらOKです。

今日はここまで。
続きはまた。(続くのか?)


問題点など:

・Ruby+Railsをインストールした状態で、rubyフォルダだけで500MB強喰います。実サイズは100MB弱なので、およそ 5倍の容量ですね。
 ファイルシステムがFATなので、RubyのようにUNIX的なシステムは厳しいのかな。ちなみに、NTFSな環境だと200MBくらい(およそ 2倍)のようです。
 USBメモリは 1GB以上必要ですね。

・ruby.exe(と思われる)の起動にやたら時間がかかります。
 WEBrickも起動しさえすれば、アプリケーションの動作はそんなに遅くはないようですが。。

2006年11月22日

Wikipedia

最近”英語版”のWikipediaがかなり使えるな!と思うようになりました。
なぜ英語版かというと、日本語のWikipediaと比較して
登録されている用語が圧倒的に多いからです。
しかもライターはその道のプロだったりすることが多いようですね。
http://en.wikipedia.org/wiki/Main_Page

何100ページもある仕様書を読む前に
概要だけでも理解しておくとか、
いろいろな使い道がありそうです。

例えば「QVT」と検索すると以下のような解説が出てきます。
これ以外にも様々な用語が登録されていますね。
http://en.wikipedia.org/wiki/QVT

                     テクニカルデプト  橋本 大輔

2006年10月26日

OOPSLA 2007(1)

 今年のOOPSLAはオレゴン州のポートランドで開かれた。ポートランドはシアトルとサンフランシスコの間で、日本では知らない人も多いところだ。ポートランドへは、ノースウェスト航空が直行便を出しているが、個人的に好きではないので、あえてカナダ航空でバンクーバー乗り換えにした。

バンクーバーに着くと、成田のチェックイン時に言われた「いったんカナダに入国してください」というのとは違っていて、米国の入国審査があって、驚いた。いつもながら、予期せぬ事態は起こるものだ。いつも行っている中国とは違って、英語が通じるので(あたりまえか)問題もなく、楽勝である。ポートランド行きの飛行機を2時間ほど待った。いやな予感はしたが、やはり、機体はプロペラ機であった。1時間ぐらいで着く距離は、たいてい小さい飛行機が飛んでいる。ポートランド飛行場につくと、トラムが乗り入れているので、市内までは簡単である。トラムに乗って、ホテルの近くで降りたら、目の前にDouble Treeホテルがあり、これまた楽勝だ。やはり米国出張は精神的にとても楽である。

OOPSLAの初日は、基調講演のタイトルが「Designed Animism」であったため、スキップして、インターネットでメール送受信をやっていた。そのあと、デモセッションに参加して、Canooの新しいバージョンを見て、アスペクト・マイニングという話を聞いた。膨大なレガシーなコードからアスペクト候補を探し出してくるというもので、なかなか面白かった。ただ、サンプルとして、lockとかを出していたのはどうかと思った。もうちょっと面白いアスペクトを候補に持って来れるといいのに。デモは、Mac OSX で行っていて、Eclipseのプラグインとしてツールは実装されていた。OOPSLAに来ると、Macを持っている人がとても多い。やはりOOエンジニアにはMacなのかもしれない。

午後は、エージェント指向UMLやUMLモデルでの横断的要件の追跡の話があったが、用事があって聞けなかった。

夜は、「Design Patterns : Beginnings & Futures」というGoFのブリシデスの追悼があった。ヘルムは欠席でオーストラリアからビデオレターを送って来た。ということで、ガンマとジョンソンの二人で、ブリシデスとGoFのアクティビティを振り返って、Q&Aに答えるという内容であった。司会は、スティーブ・フレイザーがやっていた。私にはスティーブは、XPなどのコンファレンスでいつもがビデオ撮影をしていたという記憶しかないので、ずいぶんと中心に入って来たようだ。XPの仲間が出世していくのはとても嬉しい。
ブリシデスとは、「パターン・ハッチング」という本を日本語に訳したことで、ずいぶんと仲良くさせてもらった。日本に呼ぶからと話していたのに、ついに実現できなくなってしまった。彼からは多くのことを学んで、オブジェクト指向技術への多大なモチベーションをもらった。
懐古のビデオとして、GoF裁判が流された。裁判官の席には、ケント・ベックとマーチン・ファウラーがいて、被告人の席にはGoFのブリシデス、ガンマ、ジョンソンがいる。デザインパターンを作った罪で裁かれるという、アトラクションである。私もその場にいたので、懐かしく思い起こした。
ガンマもジョンソンもすでに白髪がかなり多くなってきて、多くの月日が流れたんだなあと思ってしまった。OOPSLAの参加者も年配の人が多くなって来ているので、そろそろ新しいことはここからはでてこなくなるのでは、とさえ感じた。自分もオヤジになったということでもあるが。
Q&Aでは、ブリシデスが一番好きなパターンは何かとかGoFというのは誰が付けたのかなどの質問が出た。GoFの由来については、パターンのメーリングリストでそう付けられたのであって、決してシカゴでチェーンを振り回していた訳ではないと答えて、静かな雰囲気の中、時折の笑いもでた。

長瀬 嘉秀

2006年10月10日

知識や経験の再構築

先月からセミナー講師を担当する機会が多くありました。
人前で話すのはそんなに得意ではないので、毎回苦労するのですが、
今まで蓄積してきた知識や経験を頭の中で整理し直すいい機会だと考えています。

当たり前のことですが、人前で話す前にはその内容を一旦整理して
自分の中で噛み砕き、どう分かりやすく個々の内容を伝えるか、
さらにはどう内容をつなげてストーリーを組み立てるか、
といったことを考える作業が必要になります。
これによって知識や経験が再構築され、あいまいに認識していた内容や
誤って認識していた内容を改めることができます。

皆さんもたまに知識や経験を再構築する機会を作ってみてはいかがでしょうか?
ブログなどで情報発信してみる、というのも1つの手段だと思います。

                         テクニカルデプト  橋本 大輔

2006年07月25日

科学と魔法

長い梅雨も、もうすぐ明けようかという今日この頃、 皆様いかがお過ごしでしょうか。 梅雨は最後に各地で大きな爪跡を残しているようですが、もうすぐ雨続きの日々から抜け出し、 太陽の下で過ごせるようになりますね。なりますよね?! まぁ私はもっぱら、昼間に屋外に出て過ごす時間は極僅かではありますが。

ご無沙汰しておりました(*1)、 前回 に比べて幾分静かにお送りしてみようと思っている私 "岡部" が、 不定期にお届けする雑談コーナー第2回です。

今回のテーマは「科学と魔法」です。「科学と魔法」といえばファンタジー、 そういえば最近なにかとファンタジー分野の作品が話題に上ることが多い気がします。 私も子供の頃は、分厚い本を図書館から借りてきてはよく読んでいたものです。

ソフトウェアの世界では、もっぱら科学の力が大きいように私は思っています(*2)。 科学とは、誤解を恐れずに簡潔化するならば、「記号」と「帰納」と「演繹」です。

記号

そもそも人間は、現象をありのままに知覚しているわけではないですね。 「知覚」するということは、扱うことの出来る情報の形に当てはめているということです。 良い例かは判りませんが、そうであるが故に錯覚という現象が存在するわけです。 科学(その基礎である数学(的方法))では、それをより広義に適用し、 様々な事柄を記号として扱うことで、 複雑な考察も単純化する等して進めていけるようにしているんですね。

まぁ、普段意識せず使っている「名前」だって立派な記号です。

ソフトウェアの世界は、 少なくとも今は、 その仕組みがほぼ全て見えているままですから、 記号論だらけですね。

帰納
様々な具体的な事柄から、抽象化された法則を導くことですね。 記号化して帰納することで、共通法則を軸にして、 広範囲の事柄を抽象化して扱うことが出来るようになるわけです。
演繹
帰納とは逆に、大法則から具体的な結果について導くことですね。 三段論法なんかが該当します。 つまり、各具体的な事柄に当てはめるとどうなるか? を導くわけです。

ね、ソフトウェア自体も、ソフトウェア開発も、とっても科学的な活動でしょう? 実装技術だって、モデリングだって、みんな科学の力といって過言ではありません。

でも、ソフトウェアの世界には魔法の力も登場します。 皆さんの身近なアプリケーション等にも、魔法使いが居るでしょう?

魔法使い、それは「ウィザード」です。科学的に整然と作り上げられたソフトウェアを前に、 次に何をしたら良いのか解らなくなった時、目的に合わせて色んなお膳立てをしてくれるアレです。 なにをどうやったのか教えてくれないまま、気付くとお膳立てが済んでいる、手品師みたいなアレです。

私は、先にも述べたように、ソフトウェアにおいては科学の力が大きいと思っています。 それは、ソフトウェアがそもそも科学の力に基づいて成り立っている仕組みである,、 ということからも自明と言って良いでしょう。

でも科学というのは、時に人間の論理にはマッチしないことがあるんですね。 科学の良い所は、理論立てることで広範囲の問題を統一的に扱えることですが、 そうして用意された「これだけあれば、演繹でどんな問題も解けるでしょ」というセットを用意しても、 人間の側が使いこなせないという場合が、あるんですね。

そんな時に登場する助っ人がウィザードになるわけです。 ありがちなシチュエーションであれば、目的に応じて代わりにあれこれ操作してくれるわけですね。 「どんな問題でもこのセットがあれば解決できる」と言われても、オーバースペックである場合もありますし。

これまでの常識を覆して、いっそウィザード式の操作をメインにしてソフトウェアを開発しよう、 という動きもあります。それは、ソフトウェア開発の都合ではなく、 使う人の視点に基づいたユーザーインターフェースを提供するということでもあります。 ソフトウェア開発の都合で科学的な操作セットをそのまま押し付けるのは、 エゴであり、サボリだというわけです。

他方、だからといって、何もかもウィザード式にすれば良いかというと、そうでもありません。 科学的な操作セットが役に立つ(*3)こともありますし、 少なくともソフトウェアの内部は科学的で良いと思いますから。 ただ、機能を実現する方法と、ユーザーインターフェースの提供の仕方は、 別だということですね。 ユーザーインターフェース部分がちゃんと機能実装と分離しているならば、 使用者や目的に合わせて最適なインターフェースをラッパーとして提供すればよいのですから。

そうすれば、ソフトウェア(内部)の開発は科学の力で行い、汎用的に活用できるようにもしておきながら、 ユーザーに対しては用途や目的に応じて適切なインターフェースによってそのサブセットを提供するということが出来ます。 勿論同じユーザでも、違う用途や目的に対しても活用したいということになれば、 そのときにはインターフェースを追加したり組替えたりすれば良いですし、 原理的には同じ問題を扱っている異なるアプリケーションにおいても、 内部は同じでインターフェースの違いで対応することが可能でしょう。 オブジェクト指向であるとかコンポーネントベースの開発手法にも通ずる話ですね。

というわけで、今回はソフトウェアの構造的特徴とユーザーインターフェースのあり方について、 話題にしてみたのだと思います、多分。 それでは、またいつか、第3回でお会いしましょう。

*1
元々、筆不精なんです。書くこと自体は嫌いではないんですが。 書くことは色々と自分の為にもなりますしね。
*2
「それはオマエが理系だからだろう!」とか言われてしまうと、 そうなのかも知れませんけどね。 「理系」と「文系」については、またどこかで論じてみたいですね。 違わないかに見えて違うところと、違うかに見えて違わないところが、 あったりしますよね。 いずれにせよ、そんなにはっきりと線引きがあるとは、思わないですけれども。
*3
私は、科学的な操作セットが全くなくなってしまうのは困ります。 逆にそういう操作セットさえあれば、自分で演繹して問題に対処すれば良いので、安心です^^;
岡部 太一
テクニカルデプト デベロップメントグループ
システムエンジニア

2006年06月07日

サバレンジャー?!

技術は日進月歩、混沌とした競争社会の中、 皆様いかがお過ごしでしょうか。 この記事は、様々なことがバラバラと急速に進歩する世の中で 眩暈気味な私 "岡部" が、 不定期にお届けする雑談コーナーです。

他の真面目な記事群から浮いた内容になっていれば、何よりです。(えっ!?) *1

最初から、何か変なテンションで始めてしまいました。 後悔先に立たず、ですが、少しはテンションを戻してから、進めていきましょう。 ;-)

進歩に眩暈気味とは言いつつ、私けっこう環境オタクです。 新技術大好きです。 普段は別に「ミーハー」ということは無く、流行にも疎いのですが、 技術分野に関しては、きっと「ミーハー」なんですね。 *3

一般的にもよくあるケースで言えば、 使用するPC環境は会社のPCであってもしっかりカスタマイズする、とか。 私は、普段使用しているWebBrowserは FireFox MUAは Thunderbird ですが、ちょっと面白いExtensionを見つけるとすぐに導入して試してみたり。 *4

プライベートになると、「環境オタク」がより発揮されます。 私の自宅は・・・PCの台数こそ少ないですが、 ちょっとしたサーバールームかもしれません(汗)

本音で言うと、自宅にラックが欲しいんですが、諸事情ありまして実現いたしません(笑)

ところで、先日、暫く放置していたPodcastを整理してみたのですが・・・ そこでのチャンネルを掘り出してしまいました。

5800 RADIO SHOW
サーバ管理者や情報システム管理者である 名付けて“サバレンジャー”なアナタに向けたスペシャルプログラム! DJは赤坂泰彦。 サーバ管理者だからこそ気になる最新ニュース、 サーバ管理者のアナタの投稿で完成させる「なんでもBEST5」、 そして!サーバ管理者ならではのお悩みを解決するコーナーなど 盛りだくさんの内容となっております!

なんでしょうかね、これは(汗)

ナビゲーターに赤坂さんを起用し、結構ちゃんと作られてます。 でも、テーマがテーマだからでしょうか、 特に番組を始めてしばらくの間は微妙にやり難そうなカンジが漂ってます・・・

しかも「サバレンジャー」を連呼してます(笑)

提供がNECさんで、どうやら NECさんのサーバハードウェア販促番組なのではないか、 と私は思っています。番組内でもNECさんのサーバ紹介コーナーとかありまして。

一応 ITMdia とも提携していて、最近のグローバルなニュースなんかも (どういう基準で選んでいるかは判りませんが)見繕って紹介してくれたりもします。

まぁ、何かのときにBGM的に流しておいて、 たまに耳についたネタに含み笑いするくらいが、良い楽しみ方かもしれません。 「なんでもBEST5」では、「あぁ~、それ、あるある」なんてネタもあって、 含み笑いが出来ます。

今回はサーバーの話題が中心でした。 私はソフトウェア開発を主なフィールドとしているつもりですが、 サーバー環境のことやサーバ構築についても興味があり、 そして一般的な基準からすると、どうやらちょっとした能力者らしいです。 "好きこそ物の上手"ということかも知れませんが、 私なりにこだわりがあるのも確かです。

私が何故、サーバー(に限りませんが)の環境のことにこだわりを持っていのか、 それは、ソフトウェアを快適に動作させる為には、無視してはいられないからです。 ソフトウェア自身にとっても、ソフトウェアを動作させる"環境"にとっても、 そしてソフトウェアの使い手にとっても、又はソフトウェアの創り手とっても、 そのソフトウェアをより理想的に運用する為には、 基盤となるプラットフォームについても気を使うことが欠かせないと考えているからなのです。

私は、少なくとも自分が意を込めて創るソフトウェアには、 期待されていた以上に活用されまくって、 最後まで天寿をまっとうして欲しいのです。

さて、今度の週末はどんなサーバ構想を立てて楽しもうかしら。

*1
真面目な記事も書きます。多分。
*2
普段は静かな人間です。黙々と仕事してます。多分。
*3
興味はたくさんあります。でも実際は、追いきれません・・・
*4
他の人が使用するときに困らないように、 または自分が他のPCを使用するときに戸惑わないように、 UIであるとか操作方法に関わる部分はあまり変えないように気を付けています。
岡部 太一
テクニカルデプト デベロップメントグループ
システムエンジニア

2006年05月10日

マーチン・ファウラーセミナーへの期待

今回も宣伝です(^^;
今月末に弊社では、UMLやパターン、アジャイル開発などの分野で大家である
ThoughtWorks社のマーチン・ファウラー氏を招き、セミナーを開催します。

このセミナーではSOAとオフショアがキーワードになっており、
ファウラーの書籍「Patterns of Enterprise Application Architecture」
で紹介されたパターンとSOAがリンクした話が聞けるで私としてはこれが一番楽しみです。
それ以外にも、ThoughtWorks社がオフショア開発をどう考え、どう実践しているのか、
といった内容にも期待できます。

パターンウィーバーのサポートユーザですと
特別価格で申し込めるようですので、この際ツールを入手しつつ
講演を聞く、というのもいいのではないでしょうか(^^;

「マーチン・ファウラー来日記念  ITトレンドセミナー」
 ~SOAからオフショアまでIT業界の最新動向を探る~
テーマ:SOAとオフショア開発 (UML、アジャイルも含む)
会期:2006年5月30日(火)
会場:JA国際会議場
主催:Thought Works, Inc. 株式会社テクノロジックアート      
http://www.tech-arts.co.jp/xp/xp_agileseminar/2006.html


                         テクニカルデプト  橋本 大輔