Amazon Product Advertising APIの容赦ない変更点
Amazon Product Advertising APIの最新バージョン以降では、カスタマーレビューの内容が取得できなくなるかもしれません。レビューを表示しているアプリの製作者は、ドキュメントをチェックしたほうがよいと思います。
変更点
Product Advertising APIの2010-09-01バージョンが、昨日付けでリリースされました。
リリースノートにはこうあります。
The reviews request group no longer returns customer review content. Instead, it returns an iframe URL that contains reviews which you can imbed on a web page.*1
私なりにまとめると:
- Reviewsレスポンスグループを指定しても、返ってくるXMLにカスタマーレビューの内容が含まれなくなる
- 代わりに、レビュー埋め込み用のiframe URLが含まれるようになる
ということです。
現時点の挙動
2010-09-01バージョンの挙動を確認したところ、まだカスタマーレビューの内容が含まれていました(CustomerReviews/Review)が、いつ消えるかは分かりません2010-11-10に消えるそうです(本記事下部の追記をご参照ください)。
埋め込み用URLは CustomerReviews/IFrameURL に含まれていました。下記は実際の取得例です。
http://www.amazon.jp/reviews/iframe?akid=066ZK100NJ177KN8CF82&asin=4774142042&exp=2010-09-09T11%3A23%3A53Z&linkCode=xm2&tag=chintara-22&v=2&sig=W46Rk6k3Pbkz5s3ISqyqUUpHPJcRCYCZgaZW1X5ZPv0%3D
よく見ると「exp」で1日後が指定されています。
埋め込みURLの有効期限に注意
PDF版のテクニカルドキュメントを調べたところ、下記の記載がありました。
Each iframe URL is valid for 24 hours. If the iframe URL expires, you will receive a 403 Forbidden error code.(p.132)
24時間以内に埋め込みURLを更新しないと、iframeの中身がおかしなことになるということです。容赦ない。
追記(2010-09-08)
本件に関し、「Product Advertising APIのReviewsレスポンスグループを最近ご利用された方」宛に、Amazonから案内メールが来ました。2010-11-09をもって、レビュー内容の返却を終了するとのことです。2010-11-10以降はiframe URLのみの提供となるわけですね。
*1:"The reviews request group" は "The reviews response group" の誤記でしょう
リリースチェッカーをさくらのVPSで試験運用中
リリースチェッカーをさくらのVPSで試験運用中です。もともとWebKeepersのVDSで運用していたのですが、このまま乗り換えることになりそうです。
最近、国内のVPSサービスが充実してきています(参考:VPS比較 SaaSes, さくら, ServersMan@VPS)。
拙作のリリースチェッカーは、WebKeepersのVDSで運用していたのですが、サーバが海外にあることや、月額15ドルと国内VPSより高いことから、国内VPSに乗り換えることにしました。
どのサービスに乗り換えるか迷いつつも、初期費用ありのSaaSesは却下、スワップ領域なしのServersMan@VPSも却下して、さくらのVPSを試用することにしました。
現在リリースチェッカーは、無料期間中のさくらのVPS上で動いています。今のところCPUもメモリも充分で、さくさくです。このまま問題が起きなければ、正式に乗り換えるつもりです。
RubyからHaskellを呼び出したくてHubrisをインストールした
Hubrisという、RubyからHaskellのコードを呼ぶためのブリッジがあります。HaskellパッケージとRubyライブラリで構成されており、現在のバージョンは0.0.3です。
とある理由から、このHubrisで遊んでみようと思ったのですが、Haskellパッケージのインストールにかなり手こずったため、ポイントをまとめておきます。ちなみにRubyライブラリのほうは「gem install hubris」で簡単に入りました。
今回まとめる内容は、あくまで僕の環境(CentOS 5)でうまくいったもので、他の環境ではどうだか分かりません。誤った記述があるかもしれませんので、お気づきの際はぜひお知らせください。
Hubrisで遊びたくなった理由については、後日書くつもりです。
ざっくりした流れ
$ wget http://hackage.haskell.org/packages/archive/hubris/0.0.3/hubris-0.0.3.tar.gz $ tar xvzf hubris-0.0.3.tar.gz $ cd hubris-0.0.3 $ runhaskell Setup.hs configure (ここで dist/build/autogen/Includes.hs を編集) $ cabal install --enable-shared \ > --extra-include-dirs=/home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/i686-linux \ > --extra-lib-dirs=/home/iwamot/.rvm/rubies/ruby-1.9.1-p378/lib \ > --extra-lib-dirs=/home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib
「runhaskell Setup.hs configure」すると、ビルドに必要な dist/build/autogen/Includes.hs が生成されます。ただし、生成された内容のままでビルドすると、Hubrisが正常動作しないため、手を加える必要があります。
cabal installのオプションでは、Ruby 1.8のヘッダファイル格納先と、Ruby 1.8および1.9の共有ライブラリの格納先を渡しています。
dist/build/autogen/Includes.hs の編集
僕の環境*1では、生成された dist/build/autogen/Includes.hs の内容は下記の通りでした。
module Includes where extraIncludeDirs=["/home/iwamot/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux"]
このままでもビルドはできるのですが、extraIncludeDirsで指定されたディレクトリにヘッダファイルが格納されていないため、Hubrisの実行時にエラーが発生してしまいます。
エラー内容を参考に、下記のように編集すると、うまく動くようになりました。
module Includes where extraIncludeDirs=["/home/iwamot/.rvm/rubies/ruby-1.9.1-p378/include/ruby-1.9.1", "/home/iwamot/.rvm/rubies/ruby-1.9.1-p378/include/ruby-1.9.1/i686-linux"]
cabal installのオプション
cabal install部分を再掲します。
$ cabal install --enable-shared \ > --extra-include-dirs=/home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/i686-linux \ > --extra-lib-dirs=/home/iwamot/.rvm/rubies/ruby-1.9.1-p378/lib \ > --extra-lib-dirs=/home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib
「--extra-include-dirs」は問題ないでしょう。Ruby 1.8のヘッダファイル格納先を渡します。
問題は「--extra-lib-dirs」で、上記のように指定すると、下記ライブラリファイルの参照をインストーラに指示することになります。
- /home/iwamot/.rvm/rubies/ruby-1.9.1-p378/lib/libruby.so
- /home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib/libruby1.8.so
注意すべきポイントは2点です。
まっさらなGHC環境がお勧め
HubrisのHaskellパッケージをインストールすると、下記の依存パッケージもインストールされます。
いずれかが「--enable-shared」なしでインストールされている場合、HubrisのHaskellパッケージのインストールに失敗します。回避するには、事前に削除(cabal unregister)しておくか、「--enable-shared」付きで再インストール(cabal install --reinstall --enable-shared)しておかなければなりません。
僕は当初、Haskell Platformを使っていたのですが、依存関係の縛りで、削除も再インストールもできませんでした。そこでHaskell Platformをアンインストールし、GHC 6.12.3を入れ直し*2、インストール済みのパッケージを全削除しました。
Hubrisを実行する前に
インストールが終わればHubrisを実行できるのですが、事前に確認しておかなければならないことがあります。
共有ライブラリのロード
まず、Ruby 1.8の共有ライブラリをロードしておかなければなりません。
$ echo /home/iwamot/.rvm/rubies/ruby-1.8.7-p302/lib > /etc/ld.so.conf.d/hubris.conf $ sudo /sbin/ldconfig
Hubris実行時に検索されるライブラリファイル名は「libruby.so.1.8」です。cabal install時の「libruby1.8.so」とは異なるため、注意が必要です。
サンプルの実行
インストールメモは以上で終わりですが、せっかくなのでサンプルを動かしてみましょう。
/home/iwamot/.rvm/gems/ruby-1.9.1-p378/gems/hubris-0.0.3/sample にサンプルスクリプトが配置されています。実は、このサンプルも一部修正が必要でした。
config.ru(一部修正)
use Rack::Reloader, 0 use Rack::ContentLength require 'pp' require 'hubris' class Fibonacci hubris :source => 'Fibonacci.hs' end def arg_from env # 岩本修正ここから #env['REQUEST_URI'] ? env['REQUEST_URI'].to_s.sub(/^\//, '').to_i : 0 env['PATH_INFO'] ? env['PATH_INFO'].to_s.sub(/^\//, '').to_i : 0 # ここまで end app = proc do |env| value = Fibonacci.new.fibonacci( arg_from env ) [ 200, {'Content-Type' => 'text/plain'}, "The fib number is #{value }" ] end run app
Fibonacci.hs(修正なし、コメント行は省略)
module Fibonacci where import Foreign.C.Types import Maybe fibonacci :: Int -> Int fibonacci n = fibs !! n where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
実行
$ cd /home/iwamot/.rvm/gems/ruby-1.9.1-p378/gems/hubris-0.0.3/sample $ rackup config.ru
http://localhost:8765/10 にアクセスすると、無事「The fib number is 55」と表示されました。
今後の予定
冒頭で書いたとおり、Hubrisで遊びたくなった理由を次回以降の日記に書く予定です。
また、当然ながら、自作のHaskellコードをRubyから呼び出してみようと思っています。「http://www.engineyard.com/blog/2010/a-hint-of-hubris/」が参考になりそうです。
*2:インストール手順は「Haskell初心者の僕が試したことをまとめてみた」に書いたとおりです
Haskell Platformを入れた
以前の日記(「Haskell初心者の僕が試したことをまとめてみた」)を書いたときには知らなかったのですが、Haskell Platformという開発プラットフォームがあるんですね。http://www.sampou.org/cgi-bin/w3ml.cgi/haskell-jp/msg/480で知りました。
今のところ僕が使いたいのはGHCとCabalぐらいなので、Haskell Platformに含まれるツール群を見るかぎり、Haskell Platformに移行する必要はなさそうです。
が、GHCのサイトに:
For most users, we recommend installing the Haskell Platform instead of GHC. The current Haskell Platform release includes a recent GHC release as well as some other tools (such as cabal), and a larger set of libraries that are known to work together. This standalone GHC 6.12.3 release is aimed primarily at package maintainers and early adopters.
GHC: Download version 6.12.3
とあったり、たまたま今日新しいバージョンがリリースされたりしたので、勉強がてら手元のCentOS 5に入れることにしました。
GHCのインストール
まず、GHC 6.12.3を入れる必要があります。僕はpacoでパッケージ管理しているので、先に「sudo paco -r ghc」でGHC 6.12.2をアンインストールしました。
その後、GHC 6.12.3をインストールしました。
$ wget http://darcs.haskell.org/download/dist/6.12.3/ghc-6.12.3-i386-unknown-linux-n.tar.bz2 $ tar xvf ghc-6.12.3-i386-unknown-linux-n.tar.bz2 $ cd ghc-6.12.3 $ ./configure $ sudo paco -D make install
Haskell Platformのインストール
つづいて、Haskell Platform 2010.2.0.0をインストールしました。僕の環境では、先にmesa-libGLU-develとfreeglut-develのインストールが必要でした。
$ sudo yum install mesa-libGLU-devel $ sudo yum install freeglut-devel $ wget http://hackage.haskell.org/platform/2010.2.0.0/haskell-platform-2010.2.0.0.tar.gz $ tar xvzf haskell-platform-2010.2.0.0.tar.gz $ cd haskell-platform-2010.2.0.0 $ ./configure $ make $ sudo paco -D make install $ cabal update
これだけです。ついでに、日本語出力対応版のHUnitを「cabal install」してみましたが、問題なく動きました。
雑感
Haskell PlatformにはHaddockだのプロファイラだのも含まれています。そのうち使うことになりそうなので、GHC+Cabalの環境には戻さず、このまま行こうと思います。インストールも簡単でしたし。
おまけ
pacoも2.0.9に上げました。手順を忘れそうなのでメモ。
$ sudo paco -r paco $ wget http://downloads.sourceforge.net/project/paco/paco/2.0.9/paco-2.0.9.tar.bz2?use_mirror=jaist $ tar xvf paco-2.0.9.tar.bz2 $ cd paco-2.0.9 $ ./configure --disable-gpaco $ make $ sudo make install # make logme
HUnitで日本語を出力してみる→成功
こんなテストケース(test.hs)があるとします。
module Main where import Test.HUnit test1 = TestCase (assertEqual "アサーションのラベル" "期待値" "実際の値") tests = TestList [TestLabel "テストのラベル" test1]
これを走らせると:
Prelude> :load test.hs [1 of 1] Compiling Main ( test.hs, interpreted ) Ok, modules loaded: Main. *Main> runTestTT tests Loading package HUnit-1.2.2.1 ... linking ... done. ### Failure in: 0:"\12486\12473\12488\12398\12521\12505\12523" アサーションのラベル expected: "\26399\24453\20516" but got: "\23455\38555\12398\20516" Cases: 1 Tried: 1 Errors: 0 Failures: 1 Counts {cases = 1, tried = 1, errors = 0, failures = 1}
のように表示されてしまいます。「テストのラベル」「期待値」「実際の値」がエスケープされていて、意図通りなのは「アサーションのラベル」だけです。
意図通り表示したいのですが、どうしたものでしょうか。
エスケープの原因
まず、エスケープの原因を探る必要があります。
調べると、下記のリソースが見つかりました。
putStrLnやhPutStrLnではなくprintを日本語文字列の出力に使った場合,文字列が数値を使った表現にエスケープされてしまう点に注意してください。(中略)
エスケープの原因は,printの内部で使われているshow関数にあります。Char型のShowクラスに対するインスタンスでは,文字列をどんな環境でも表示可能にするため,UnicodeでDELよりも後にくる文字をエスケープするよう定義されています(中略)
エスケープされた文字列は,Readクラスのreadメソッドを使うことで元に戻せます。
第39回 一般向けの「Haskell Platform」とインストール・ツールの「cabalコマンド」(5ページ目) | 日経 xTECH(クロステック)
なので、テスト結果出力部分でprint関数なりshow関数なりが呼ばれている可能性が高そうです。
show関数が使われていた
実際にHUnitのコードを追ってみると、予想通りでした。
Test/Text.hs
showPath nodes = foldl1 f (map showNode nodes) where f b a = a ++ ":" ++ b showNode (ListItem n) = show n showNode (Label label) = safe label (show label) safe s ss = if ':' `elem` s || "\"" ++ s ++ "\"" /= ss then ss else s
Test/Base.hs
assertEqual preface expected actual = unless (actual == expected) (assertFailure msg) where msg = (if null preface then "" else preface ++ "\n") ++ "expected: " ++ show expected ++ "\n but got: " ++ show actual
各所でshow関数が使われています。これがエスケープの原因です。
read関数をかます
当該部分にread関数をかまし、ビルド〜インストールし直せば、意図通りに出力できそうです。
実際にやってみます。まず、HUnitのtarボールを展開します。
$ cd ~/.cabal/packages/hackage.haskell.org/HUnit/1.2.2.1 $ tar xzf HUnit-1.2.2.1.tar.gz $ cd HUnit-1.2.2.1
そして、Test/Text.hsとTest/Base.hsを編集します。diffは下記の通りで、read関数をかましているだけです。
Test/Text.hs
$ diff -u Test/HUnit/Text.hs.org Test/HUnit/Text.hs --- Test/HUnit/Text.hs.org 2010-07-22 14:09:01.000000000 +0000 +++ Test/HUnit/Text.hs 2010-07-22 14:10:08.000000000 +0000 @@ -113,7 +113,7 @@ showPath nodes = foldl1 f (map showNode nodes) where f b a = a ++ ":" ++ b showNode (ListItem n) = show n - showNode (Label label) = safe label (show label) + showNode (Label label) = safe label (read (show label)) safe s ss = if ':' `elem` s || "\"" ++ s ++ "\"" /= ss then ss else s
Test/Base.hs
$ diff -u Test/HUnit/Base.hs.org Test/HUnit/Base.hs --- Test/HUnit/Base.hs.org 2010-07-22 14:01:40.000000000 +0000 +++ Test/HUnit/Base.hs 2010-07-22 14:00:36.000000000 +0000 @@ -73,7 +73,7 @@ assertEqual preface expected actual = unless (actual == expected) (assertFailure msg) where msg = (if null preface then "" else preface ++ "\n") ++ - "expected: " ++ show expected ++ "\n but got: " ++ show actual + "expected: " ++ read (show expected) ++ "\n but got: " ++ read (show actual) -- Overloaded `assert` Function
read版をインストール
ビルドの準備ができたので、「cabal install」します。
$ cabal install
問題なくインストールできました。
テスト実行
さて、テストを実行します。意図通り表示されるでしょうか。
Prelude> :load test.hs [1 of 1] Compiling Main ( test.hs, interpreted ) Ok, modules loaded: Main. *Main> runTestTT tests Loading package HUnit-1.2.2.1 ... linking ... done. ### Failure in: 0:テストのラベル アサーションのラベル expected: 期待値 but got: 実際の値 Cases: 1 Tried: 1 Errors: 0 Failures: 1 Counts {cases = 1, tried = 1, errors = 0, failures = 1}
されました!
HUnitを使ってみた(ついでにHLintも)
HaskellのユニットテストフレームワークであるHUnitを使ってみました。テスト対象のコードは、先日書いたsign関数です。
HUnitのインストール
なにはともあれ、まずはHUnitをインストールしました。Cabalのおかげで簡単に入れられました。
$ cabal install HUnit
テスト対象コードのモジュール名検討
つづいて、テスト対象コードのモジュール名を何にするか検討しました。このモジュールは「キープリスト」というWebアプリケーションで使う予定であり、AmazonのAPIに関わるものなので、「KeepList.Amazon」に決めました。
ファイル構成の検討
つづいて、テスト対象コードとテストコードをどのように配置するか検討しました。モジュール名の名前空間の階層をそのまま生かし、テストコードを「tests」ディレクトリに入れることに決めました。
$ tree . |-- KeepList | `-- Amazon.hs `-- tests `-- KeepList `-- Amazon.hs
テスト対象コードの記述
つづいて、テスト対象コード(KeepList/Amazon.hs)を記述しました。といっても、先日書いたコードのモジュール名を「KeepList.Amazon」に変え、main関数を削除し、sign関数の名前を「signature」に変えただけです。
module KeepList.Amazon (signature) where import Data.ByteString.Lazy.Char8 (pack) import Data.Digest.Pure.SHA (hmacSha256, bytestringDigest) import Data.ByteString.Lazy (unpack) import Codec.Binary.Base64 (encode) signature :: String -> String -> String signature secret_key message = encode $ unpack $ bytestringDigest $ hmacSha256 (pack secret_key) (pack message)
テストコードの記述
つづいて、テストコード(tests/KeepList/Amazon.hs)を記述しました。署名の例はAmazon Product Advertising APIのドキュメントから集めました。テストの書き方は「第16回 Haskellでのテストの自動化を考える(2ページ目) | 日経 xTECH(クロステック)」を参考にしました。
module Main where import Test.HUnit import KeepList.Amazon secret_key = "1234567890" tests = test [ "TuM6E5L9u/uNqOX09ET03BXVmHLVFfJIna5cxXuHxiU=" ~=? signature secret_key ("GET\necs.amazonaws.co.uk\n/onca/xml\nA" ++ "WSAccessKeyId=00000000000000000000&Act" ++ "or=Johnny%20Depp&AssociateTag=mytag-20" ++ "&Operation=ItemSearch&ResponseGroup=It" ++ "emAttributes%2COffers%2CImages%2CRevie" ++ "ws%2CVariations&SearchIndex=DVD&Servic" ++ "e=AWSECommerceService&Sort=salesrank&T" ++ "imestamp=2009-01-01T12%3A00%3A00Z&Vers" ++ "ion=2009-01-01"), "cF3UtjbJb1+xDh387C/EmS1BCtS/Z01taykBCGemvUU=" ~=? signature secret_key ("GET\necs.amazonaws.com\n/onca/xml\nAWS" ++ "AccessKeyId=00000000000000000000&Assoc" ++ "iateTag=mytag-20&Item.1.OfferListingId" ++ "=j8ejq9wxDfSYWf2OCp6XQGDsVrWhl08GSQ9m5" ++ "j%2Be8MS449BN1XGUC3DfU5Zw4nt%2FFBt87cs" ++ "pLow1QXzfvZpvzg%3D%3D&Item.1.Quantity=" ++ "3&Operation=CartCreate&Service=AWSECom" ++ "merceService&Timestamp=2009-01-01T12%3" ++ "A00%3A00Z&Version=2009-01-01"), "aMFgBNKPrz9PRR9Ato7yanlaG/PkQsNxIWYbLD1V9Zc=" ~=? signature secret_key ("GET\necs.amazonaws.jp\n/onca/xml\nAWSA" ++ "ccessKeyId=00000000000000000000&Associ" ++ "ateTag=mytag-20&ListType=WishList&Name" ++ "=wu&Operation=ListSearch&Service=AWSEC" ++ "ommerceService&Timestamp=2009-01-01T12" ++ "%3A00%3A00Z&Version=2009-01-01"), "H5u4W10g0vmyB1KA6hmkrea36AFvSryL9SQfPejvWNs=" ~=? signature secret_key ("GET\necs.amazonaws.com\n/onca/xml\nAWS" ++ "AccessKeyId=00000000000000000000&Assoc" ++ "iateTag=mytag-20&ListId=34AN6HPUN5AMX&" ++ "ListType=WishList&Operation=ListLookup" ++ "&ResponseGroup=ListItems%2COffers%2CIm" ++ "ages&Service=AWSECommerceService&Times" ++ "tamp=2009-01-01T12%3A00%3A00Z&Version=" ++ "2009-01-01"), "kEXxAIqhh6eBhLhrVMz2gt3ocMaH/OBVPbjvc9TG8ao=" ~=? signature secret_key ("GET\necs.amazonaws.com\n/onca/xml\nAWS" ++ "AccessKeyId=00000000000000000000&Assoc" ++ "iateTag=mytag-20&BrowseNodeId=465600&O" ++ "peration=BrowseNodeLookup&ResponseGrou" ++ "p=BrowseNodeInfo%2CTopSellers%2CNewRel" ++ "eases%2CMostWishedFor%2CMostGifted&Ser" ++ "vice=AWSECommerceService&Timestamp=200" ++ "9-01-01T12%3A00%3A00Z&Version=2009-01-" ++ "01"), "I2pbqxuS/mZK6Apwz0oLBxJn2wDL5n4kFQhgYWgLM7I=" ~=? signature secret_key ("GET\necs.amazonaws.com\n/onca/xml\nAWS" ++ "AccessKeyId=00000000000000000000&Assoc" ++ "iateTag=mytag-20&Condition=New&ItemId=" ++ "B0011ZK6PC%2CB000NK8EWI&Merchant=Amazo" ++ "n&Operation=SimilarityLookup&ResponseG" ++ "roup=Offers%2CItemAttributes&Service=A" ++ "WSECommerceService&SimilarityType=Inte" ++ "rsection&Timestamp=2009-01-01T12%3A00%" ++ "3A00Z&Version=2009-01-01") ]
テストの実行
以上で、テストが実行できるようになりました。実行すると、下記の通り、6ケースとも成功しました。
$ ghci GHCi, version 6.12.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :load tests/KeepList/Amazon.hs [1 of 2] Compiling KeepList.Amazon ( KeepList/Amazon.hs, interpreted ) [2 of 2] Compiling Main ( tests/KeepList/Amazon.hs, interpreted ) Ok, modules loaded: Main, KeepList.Amazon. *Main> runTestTT tests Loading package HUnit-1.2.2.1 ... linking ... done. Loading package array-0.3.0.0 ... linking ... done. Loading package syb-0.1.0.2 ... linking ... done. Loading package base-3.0.3.2 ... linking ... done. Loading package bytestring-0.9.1.6 ... linking ... done. Loading package containers-0.3.0.0 ... linking ... done. Loading package binary-0.5.0.2 ... linking ... done. Loading package SHA-1.4.1.1 ... linking ... done. Loading package dataenc-0.13.0.2 ... linking ... done. Cases: 6 Tried: 6 Errors: 0 Failures: 0 Counts {cases = 6, tried = 6, errors = 0, failures = 0} *Main> :q Leaving GHCi.
HLintによるコードチェック
テストは通ったのですが、いまひとつコードの書き方に自信がないので、「How to write a Haskell program - HaskellWiki」で知ったHLintでコードをチェックすることにしました。
HLintのインストールは下記の手順でできました。
$ cabal install happy $ cabal install haskell-src-exts $ cabal install hlint
コードをチェックした結果が下記のものです。
$ hlint KeepList/Amazon.hs No suggestions $ hlint tests/KeepList/Amazon.hs tests/KeepList/Amazon.hs:6:1: Warning: Use camelCase Found: secret_key = ... Why not: secretKey = ... 1 suggestion
テスト対象コードは問題なしでしたが、テストコードには一つ問題が見つかりました。『変数名の「secret_key」だけどさ、キャメルケースの「secretKey」にしたら?』ということですね。
コードは割愛しますが、テストコードを修正し、無事「No suggestions」となりました。じつにありがたいツールです。
今後の展望
今回はテスト対象コードが一つだけだったので、HUnitの「runTestTT」でテストを走らせましたが、数が増えてきたら、この方法では手間がかかって仕方ありません。
「第16回 Haskellでのテストの自動化を考える(4ページ目) | 日経 xTECH(クロステック)」で紹介されているような、Cabalによる複数テスト実行が必要になると思っています。
削除できなくなったTwitterの検索メモが削除できるグリモン書いた
書きました。
リアルタイム検索結果が0件になると検索メモが削除(解除)できなくなるんですが、なんでこんな仕様なんでしょうね。
ともあれ、不必要な検索メモが削除できて、僕はすっきりしました。
追記(2010-07-20)
バージョンを1.1.0に上げました。リアルタイム検索結果が0件の場合でも、検索メモが保存できるようになっています。このほうがテストしやすいので。
追記その2(2010-07-20)
何度もすみません。バージョンを1.1.1に上げました。@include に「https://twitter.com/*」を追加しています。