2007年6月アーカイブ

DREAM THEATERの新譜Systematic Chaosが出てます。Megadethのまだ持っていない旧譜やOzzyの新譜も欲しいし、マイケルシェンカーとか昔の人(ある意味失礼)のCDも欲しいし、THE ANSWERもかなり欲しい。なんて悩んでいて、すぐに買うのは控えてましたが、Napsterに早くも登録されていたので聴いてみました。

私の聴きたいDREAM THEATERそのものだ。 これは大満足です。近いうちに買う予定。

ところでDREAM THEATERもRoadrunnerに移籍してたようだ。MEGADETHの新譜もRoadrunnerから。ユナイテッド・アボミネイションズなんて、発売のかなり前からNapsterでダウンロード可能になっていたし、Roadrunnerの販売戦略なんでしょう。良いアルバムは聴いたらCDが欲しくなる(笑)

WEB+DB PRESS VOL.39

| コメント(0)

WEB+DB PRESS Vol.39買いました。

先日書いたとおり今回は、あまり期待していなかったわけですが、ぶっちゃけその通りでした。いや私にとって面白みのある記事が少なかったと言うだけで、内容が悪かったわけではないかも知れません。

第一特集の構成管理はSubversionに関しては、ここ半年、散々自分で悩んだのでスルー。半年前だったらありがたかった。Mavenに関しては単に今Javaは殆ど触ってないのでスルー。

第一特集はそれでも、パラパラと内容を確認したからまだましか。第二特集は完全にスルー(笑)
私がPHPの新情報に興味がないだけですが。

第三特集はCSS。一通り読んだ。でも先日危惧したとおり少々基本過ぎでした。知識の確認としては良かったか。IEのアンダースコアハックというのは知らなかった。有名ですか?ちょっと前に知ってたら使ったかも知れない。知らなくて良かった(?)

以下もざーっと見て、特に見所なし。お、今、私が夢中なRailsの新連載が!と喜んだのもつかの間、Emcasとviの話って…おい。私はEmacs派ですが(笑)
でもRailsの連載でそんな内容はいらないかなと。

あ、最後方のの「スケーラブルWebシステム工房」。実際にやろうとは思いませんが内容は非常に面白かったです。うん買って良かった(汗)

VOL.40に期待します。

Helperの謎

| コメント(2)

URLとして、

http://hogehoge.com/home/

という表記が良かったので、

app/controllers/home_controller.rb app/helpers/home_helper.rb app/views/home/index.rhtml

という3セットを作って、index.rhtml内で使いたいhelperメソッドをhome_helper.rbに記述したのだが、何故かhelperメソッドが見つからないと言われる。具体的には次のようなプログラム。

# =-=-= home_controller.rb =-=-=-=-=-= class HomeController < ApplicationController def index end end # =-=-= home_helper.rb =-=-=-=-=-= module HomeHelper def hoge(str) str.upcase end end # =-=-= index.rhtml =-=-=-=-=-= <%= hoge('abc') %>

そこで試しにhome_controller.rbに明示的に以下のように宣言を書いてみると動いた。

# =-=-= home_controller.rb =-=-=-=-=-= class HomeController < ApplicationController helper :home # 明示的に def index end end

しかし、home_helper.rb(HomeHelperクラス)は規約に則っているので宣言は必要ないはずだ。おかしい。

原因を確かめるべく、再びコントローラに記述したhelper :homeの行を削除して元に戻してみると・・・なぜか今度はエラーとはならずちゃんと動く。う~む、気持ち悪い。

あらかじめ断っておきますが、オチはありません。

やっぱり「あらかじめ」は最初に使いたい。よく南武線に乗ってから、「京浜東北線が○○の理由により、現在運転を見合わせております。あらかじめご了承下さい。」などという放送がなされることがあるが、まったくあらかじめっていない。それならば、さっき先に来た反対方向、立川方面行きに乗って溝ノ口経由で行きたかった。

いきなり脱線してしまったが、Rubyの配列の要素数はsizeメソッドでもlengthメソッドでも良いらしい。ずっと何かの本にたまたま載っていたlengthを使っていたが、最近買ったRails本「Ruby on Rails入門―優しいRailsの育て方」ではsizeを使っていたのでアレっと思っただけです。

ひょっとして、全てのオブジェクトに実装されている?

irb(main):001:0> [1,2,3].size => 3 irb(main):002:0> [1,2,3].length => 3 irb(main):003:0> "123".size => 3 irb(main):004:0> "123".length => 3 irb(main):005:0> 123.size => 4 irb(main):006:0> 123.length NoMethodError: undefined method `length' for 123:Fixnum from (irb):6 from :0 irb(main):007:0> 123.5.size NoMethodError: undefined method `size' for 123.5:Float from (irb):7 from :0 irb(main):008:0> 123.5.length NoMethodError: undefined method `length' for 123.5:Float from (irb):8 from :0

Fixnumはsizeがあってlengthがない、Floatはどちらもないのが面白い。Fixnumのsizeは何を表すのだろうと思い、調べたら実装上のバイト数らしい。

irb(main):018:0> 1234567890.size => 4 irb(main):019:0> 12345678901.size => 8 irb(main):020:0> 12345678901234567890.size => 8 irb(main):021:0> 123456789012345678901234567890.size => 16

なかなか面白い。しかし、その理由ならFloatにsizeがあっても良いように思われるのだが。まぁ、配列と文字列以外では必要なさそうなので、深く考えない事にしよう(オチなし)

デバッグプリント

| コメント(0)

自分のための覚え書き。

デバッグのためログにいろいろと出力する場合、logger.debugに食わせてオブジェクトの内容を簡単にダンプする方法。

1. obj.to_s
2. obj.inspect
3. obj.pretty_inspect

1.は数値や文字列など段純なオブジェクト向き。コンテナーなどの場合はオブジェクトIDの文字列表記となる。

2.はコンテナのような複雑なオブジェクトの内容が分るように文字列に変換してくれる。

3.はもっと見やすく整形した文字列に変換してくれる。

reset_column_information

| コメント(0)

DBマイグレーションで既に存在するテーブルにカラムを追加後、そこに他の項目値によってデフォルト値を自動で突っ込みたくなり、少々はまりましたので、覚え書き。

Hogeというモデルがあり、progressという項目に0 .. 9の範囲で進捗度が格納されているとする。

progressの9は完了なのだが、9に設定された日を格納するcomplete_dateというdate型の項目を追加したい。既存のレコードにはprogressが9で、complete_dateがNULLの場合、complete_dateに今日の日付を入れる。

で、マイグレーションでは普通にRubyのコードも書ける様なので、こんな風にしてみた。

class AlterHoges < ActiveRecord::Migration
   def self.up
     add_column :hoges, :complete_date, :date
     Hoge.update_all "complete_date = now()", "progress = 9 AND complete_date is null"
   end
 
   def self.down
     remove_column :hoges, :complete_date
   end
 end

しかし、うまくいかない。小一時間んで、RailsによるアジャイルWebアプリケーション開発のマイグレーションの項目を読み直して見たところ、発見。

モデルの変更があったことをActiveRecordに知らせないといけない。よく考えると当たり前だ。具体的には下記をadd_columnとupdate_allの間に挟むということ。

Hoge.reset_column_information

RailsによるアジャイルWebアプリケーション開発はRails0.9ベースに書かれていて、脚注と付録で1.0をサポートしている、結構古めの内容だが、Railsの全体と、重要なイディオムを習得するために最近Railsをやり始めた人もやはり目を通しておくべき本だと思います。

Windows版Safari

| コメント(0)

Safari 3のパブリックβ版がリリースされ、ご存じの通りWindowsに対応しています。

知ったのは数日前の発表の直後で、もちろんその日の内にインストールしてみたのですが、日本語ページは全くまともに表示されず、がっかりしてBlogにも書かなかった(笑)

先ほどApple Software Updateが当たって、Safariが更新されたので試しに起動してみると、ちゃんと日本語ページでも表示されるようになってた。

たしかに、いくつかのページを見てみた感触だとAppleが言うようにIEよりもかなり体感速度が速く感じます。

暫く使ってみても良いかなと思ったのですが、会社のMacでもSafariを常用にしていない。何故かというと、マウスジェスチャーとはてなのタブ入力のAjaxによる補助([を入れたらコンプリーションが始まる機能)が使えないから。

Windows版も同様に上記が使えなかったので、残念だけど、常用はあきらめ。

ただ、Safariの動作確認がWindowsでもできるのは、開発者としては、かなり意義があると思う。もっともMacのSafariと全く同じ挙動をしてくれるならですが(笑)

ハゲタカⅡ

| コメント(0)

今週の通勤用にと先週末に買った本ハゲタカ2(上)ハゲタカ2(下)。非常に面白くて、隙あらば読み進んだため1週間持たなかった(苦笑)

前作ハゲタカ(上)ハゲタカ(下)が面白かったという記憶で買ったのですが、間違いではなかったです。

ただ、前作の内容が良く思い出せないので、もう一度手にとってパラパラと捲ってみようと思ったのだが、どこにもない。おかしい。ひょっとして買った読んだと思ったのは気のせいか??いや今回の登場人物は良く覚えているし散漫にシーンは思い出せるのだが、話の筋が全く思い出せない。老人力がさらに高まったか。

NHKでドラマ化もされていたようで。元々バイアウト 上バイアウト 下というタイトルだったのが、文庫化の際にハゲタカⅡになったようで。タイトルはバイアウトの方が良かったかなと思います。Ⅱってのはどうかと。それに思わずバイアウトはⅡの続きかと思ってAmazonで買いそうになった(笑)

以前Tracのテーブル定義を紹介しましたが、これを調べた理由は、まだ完了していないマイルストーンに含まれる解決済みを含む全てのチケットを表示するレポートが欲しかったから。

特に難しい事は何もないのでSQLさえ書ければ、他のレポートのQueryを参考に誰でもできるでしょうが、せっかくなので公開しておきます。

SELECT p.value AS __color__,
    t.milestone AS __group__,
    (CASE status 
       WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;'
       ELSE 
         (CASE owner WHEN '$USER' THEN 'font-weight: bold' END)
     END) AS __style__,
    id AS ticket, summary, component, status, 
    resolution,version, t.type AS type, priority, owner,
    changetime AS modified,
    time AS _time,reporter AS _reporter
   FROM ticket t
   LEFT JOIN enum p ON p.name = t.priority AND p.type = 'priority'
   INNER JOIN milestone m ON m.name = t.milestone
   WHERE m.completed = 0
   ORDER BY (milestone IS NULL), milestone, (status = 'closed'), 
         (CASE status WHEN 'closed' THEN modified ELSE (-1)*p.value END) DESC

新しいレポートの追加のしかたは「チケットを見る」で「レポート一覧」に行き、「レポートの登録」をクリックし、「レポート名」「レポートについての説明」を適当に入力し、「レポートのSQL」に上記SQLを貼付けて「保存」します。

これで「レポート一覧」ページに新しいレポート種類が追加されたはずです。

Last.fmファンの皆様こんばんは。

iPodで聴いた曲も、iTunesと同期した時にLast.fmに送ってくれるiSproggler。もれなく最近聴いている曲をScrobbleできるという趣向です。

使う上での注意点をおさらいしておきます。

標準のLast.fm iTunesプログラムのScrobbleを止める

標準プログラム自体を終了ではなく、Scrobbleだけを止めます。というのもiSprogglerはScrobbleだけしかしてくれないので、今聴いている曲をお気に入り(ラブ)にしたり、友達に紹介したり、タグ付けしたりといった、ソーシャルな機能を使いたいからです。Scrobbleしていなくても聴いている曲のCDジャケットやアーティストの説明(英語ですが)も見られるので、標準プログラムは動かしておきましょう。

Scribbleを止めるには「ツール」メニューから「Scribbleを有効にする」のチェックを外すか、タスクバーのアイコンを右クリックし、コンテキストメニューから「Scribbleを有効にする」のチェックを外します。

iSprogglerを設定する

インストール自体は簡単なので割愛し、設定です。iSprogglerを起動すると、タスクバーにLast.fmマークが表示されるので、右クリックしてコンテキストメニューを表示し「Preferences」を選択します。

iSprogglerPreferences.jpg

UsernameとPasswordはLast.fmサイトにログインするときと同じです。

設定はEnable iPod SupportとEnableMultiple iPod Playsをチェックします。これでiTunesと同期した際に、スマートプレイリストの「最近再生した項目」から未送信分をScrobble(iSproggler用語ではSubmitかな)します。

Windowsにログイン時にiSprogglerも自動起動させたいので、Run at Loginにもチェック。

iPodと同期

家に帰って来てiPodをPCに接続したら、iTunesの再生を開始する前に、iPodで聴いた曲が最近再生した項目に追加されるのを待ちます。念のためにiPodの同期中(iPodのデバイス表示横のアイコンがぐるぐる回っている状態)が終わるまでは再生を待った方がよいと思われます。
iSprogglerがSubmitを開始したら、再生しても大丈夫なはずです。順序よく送信してくれている様です。

送信状態はコンテキストメニューから「Statistics」を選択すると見られます。

iSprogglerStatistics.jpg

「Songs Queued for Submission」という値が、送信待ちの曲数です。

Submitのエラー

家に帰ってiPodを同期すると、iSprogglerがよく通信エラーでタスクバーに青いエラー状態アイコンのままになっていることがあります。憶測ですが、Last.fmサーバの負荷が高いときには連続した送信はかなりの頻度でエラーになってしまう様です。この状態でiTunesを再生紙続けてもiSprogglerのQueueにはたまっていくので、いつかはちゃんと送信し終わる様ですが、少し気持ち悪い。おそらく大丈夫だとは思いますが、気になる方は標準プログラムの方が安全かも知れません。いきなりBanされたら凹む。私が有料メンバーになっている理由の一つはBanは止めてという意思表示だったりします(笑)

Amazonアソシエイツに商品プレビューなるフィーチャーが追加されました。

このブログでも商品紹介でよくAmazonのテキストリンクを貼っていますが、そのアンカーにカーソルを置くと、商品イメージを含む紹介のポップアップが表示されるというもの。

早速使ってみる。

そろそろWEB+DB PRESSが発売される時期になってきたので、これ。WEB+DB PRESS Vol.39

ちょっちうるさい気がしないでもないが、これでサイドバーはいちいち更新しなくて良い気もするので更新が楽になるかもしれない。(言うほど更新していないが)

さてWEB+DB PRESS VOL 39について、今回は表紙から想像するに、メインの特集が業務システム系から離れた私には、ちょっとどうでも良さそう(笑)な構成管理について、第2特集が今仕事で使っているPHPについて。ただPHPはお気軽にモジュールを追加して機能拡張できない類いの言語なので、いまいち期待できない。その辺りについてPHPを知らない幸せな人のために「そろそろPHPに関して一言いっとくか 404 Blog Not Found」が分かりやすい。そうそうDan Kogai氏の対談記事はいつも楽しみです。

第3特集が、今の私には一番興味深そう。「プログラマのための CSS 基礎講座」と読める。あんまり基礎すぎないことを期待。

まぁ、なんだかんだ言ってもいつも買ってます。

binding

| コメント(0)

タイトルはbindingですが、直接的に組み込み関数のbindingやBindingクラスの事ではありません。関係はありますが。

最近、書いているAmazon ECSを検索して、ごにょごにょする処理で、ECSのResponseの中(ResponseGroup=Mediumには含まれている)にBindingという項目があります。本の種類(親書、単行本、文庫)などが取得できます。

そこで、ECSの情報をキャッシュするテーブルEcsBookというクラスを作って、binding項目もそのままbindingという項目名としました。

class CreateEcsBooks < ActiveRecord::Migration def self.up create_table :ecs_books do |t| t.column :asin, :string ... t.column :binding, :string ...

そうすると、DBからこのテーブルのレコードを読んでくる際

TypeError (wrong argument type String (expected Proc/Binding)): Y:/usr/local/InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:335:in `eval' ...

こんなエラーが発生するようになった。

実は、このエラーがこの項目bindingのせいだと気づいたのは、何時間も悩んだあげく、Ruby on Rails: beware of reflection errors [<blink> Tech notes for the greater good]というページをググって見つけたから。

英語は不得意なもので、正確には分らないですが、evalやbindingとかBugとか言っている。
これはActiveRecordがbindingというカラム名を誤認識して、リフレクションがおかしくなるのでは?と気づきました。

項目名bindingをecs_bindingに変えてみたところ見事、問題解決。

しかし分りにくいな。

先日のAmazon ECSを検索するサンプルクラスですが、いろいろと問題が。

まず、致命的なところでは、このクラスItemSearchとItemLookupに対応しているつもりなのに、ItemLookup時のエラー応答がハンドリングできていない。

xpath = "ItemSearchResponse/Items/Request/Errors/Error"

というXPathでエラー応答があるかどうかをチェックして、エラーの場合はコードとメッセージを取得しているのだが、ItemSearchをハードコード(死)

xpath = "#{@response_node_name}/Items/Request/Errors/Error"

こうだった。

また、このクラスはlibディレクトリの下において、Controller/Helper/Modelとは別扱いにしたのだが、そうするとloggerオブジェクトも使えなくて困った。上記のエラーコードとメッセージをlogger.warn()しておきたかった訳です。

しかしよく考えると、Controller/Helper/Moddelからloggerオブジェクトをいつでも使えると言うことは、loggerはクラスメソッド扱いか。明示的にクラス名を指定して

@error_code = element.text('Code') @error_message = element.text('Message') ApplicationController.logger.warn 'error_code: ' + @error_code ApplicationController.logger.warn 'error_message: ' + @error_message

でOKだった。

Railsのコードを細々と書いています。

やりたいことをRubyの文法でどう表現するのかとまどうことが多く、思い切って週末にプログラミングRuby 第2版 言語編を買ってきました。

早速続きのコードを書きながら、分らない事を索引で引いて、ページを開く事を数回続けた結果、まったく索引のページにその記述がない!こんなに間違いの多い索引を平気で出版するとはどういうことかと、出版社に文句のメールを書こうかと思い始めたところ、索引の最初のページの脚注に説明がありました。

この日本語版では、元々1冊だった英語版原書を『プログラミングRuby第2版言語編』と『プログラミングRuby第2版ライブラリ編』に分冊しているため、次のように区別しています。ゴシック体はこの巻のページ番号です。斜体は他方の巻のページ番号です。

皆様もお気を付け下さい(汗)

プログラミングRuby 第2版 ライブラリ編も欲しいが、両方合わせて¥8,200円。うむ。

慣れない言語に四苦八苦しながら(といいつつ、かなり楽しんでいる)、Amazon ECSからデータを引っ張ってくるクラスを書いてみた。
まだRubyに不慣れなので、かなりアレなコードだと思われるが、夢中になってるとブログに書くのも忘れるので、とりあえずのネタとして。

require 'net/http' require 'cgi' require 'rexml/document' class AmazonEcs attr_reader :error_code, :error_message @@common_params = { :Service => 'AWSECommerceService', :AWSAccessKeyId => 'XXXXXXXXXXXXXXXXXXXX', :Version => '2007-05-14', :AssociateTag => 'xxxxxxxxxxx', :Operation => 'ItemSearch', :ResponseGroup => 'Medium,BrowseNodes' }; def initialize(book) @sw = SearchWord.new @sw.set_by_book(book) end def item_search h = {} @@common_params.each do |key,val| h[key] = val end if @sw.isbn.blank? h[:SearchIndex] = 'Books' h[:Title] = @sw.title unless @sw.title.blank? h[:Author] = @sw.author unless @sw.author.blank? h[:Keyword] = @sw.keyword unless @sw.keyword.blank? @response_node_name = 'ItemSearchResponse' else h[:SearchIndex] = 'Books' if @sw.isbn.length > 10 h[:IdType] = 'ISBN' if @sw.isbn.length > 10 h[:Operation] = 'ItemLookup' h[:ItemId] = @sw.isbn @response_node_name = 'ItemLookupResponse' end url = mk_url(h) @xml = aws_request(url) if has_xml_error?() return nil end first_ecs_book() end def mk_url(h) # RESTで必要なパラメータをURL形式に変更 arr = [] h.each do |key,val| arr << key.to_s + "=" + CGI::escape(val.to_s) end paramString = arr.join('&') URI.parse("http://webservices.amazon.co.jp/onca/xml?" + paramString) end def aws_request(url) return REXML::Document.new(Net::HTTP.get(url)) end def has_xml_error? # エラーチェック xpath = "ItemSearchResponse/Items/Request/Errors/Error" @xml.get_elements(xpath).each do |element| @error_code = element.text('Code') @error_message = element.text('Message') return true; end return false; end def first_ecs_book xpath = "#{@response_node_name}/Items/Item" @xml.get_elements(xpath).each do |element| ecs_book = EcsBook.new ecs_book.asin = element.text('ASIN') ecs_book.isbn = element.text('ItemAttributes/ISBN') ecs_book.title = element.text('ItemAttributes/Title') ecs_book.author = element.text('ItemAttributes/Author') ecs_book.manufacturer = element.text('ItemAttributes/Manufacturer') ecs_book.binding = element.text('ItemAttributes/Binding') ecs_book.publication_date = element.text('ItemAttributes/PublicationDate') ecs_book.small_image_url = element.text('SmallImage/URL') ecs_book.medium_image_url = element.text('MediumImage/URL') ecs_book.large_image_url = element.text('LargeImage/URL') ecs_book.detail_page_url = element.text('DetailPageURL') return ecs_book end nil end end

中で使われている、SearchWordとEcsBookというクラスはそれぞれ、画面からの検索情報を渡すためのプレースホルダー、およびAmazonECSからの結果を保持し、DBへ格納するためのActiveRecordです。

ISBNが指定されている場合は、優先してISBN検索をするようにしたのだが、最近買った本(具体的には泣き虫弱虫諸葛孔明第弐部)のISBNを入れてみたところ、うまくいかない。

この本はISBNが従来の10桁ではなく13桁になっている(詳しくはWikipediaを参照のこと)。

ISBNが11桁以上だったら、IdTypeパラメータをISBNに設定(このとき、SearchIndexパラメータも必要となる)すると、ItemLookupオペレーションが動くことを発見。ちなみに10桁のISBNは、ASINと一致なので、IdTypeはASIN、もしくは指定しない(=ASIN)である。ASINの場合、面倒だがSearchIndexパラメータが指定されると逆にエラーとなる。
APIドキュメントによると、JPではIdType=ISBNはサポートされてないことになっているが、使えるから良いか。

どうせなら10桁の時も、IdType=ISBNで取得させてくれれば楽だと思うのだが、そうはなっていない。

blank?

| コメント(0)

RailsのおさらいもかねてWEB+DB VOL.32からの連載「Ruby on Rails Way」を読み返してみた。

そこでblank?メソッドを発見。前にも読んでるはずなのだが、やはり必要に迫られていないと、全く覚えていない物だ。

if str.nil? || str.empty? ... end

を一発で

if str.blank? ... end

と書けて気持ちがよい。Javaで仕事していたときは、Rubyの様な特異メソッドなぞは使えないので、普通に

if (Utils.isBlank(obj.getProperty())) { ... }

なんて、やってたのを思い出す(笑)

このアーカイブについて

このページには、2007年6月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2007年5月です。

次のアーカイブは2007年7月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。