メソッドの渡すHashもきっちりチェックしたい

http://d.hatena.ne.jp/walf443/20080524/1211650071

前の記事でコンストラクタに渡せるHashのキーと値を宣言的に書くことで見通しが良くなると書きましたが、コンストラクタに限らず、メソッドにオプションとして渡すHashもきっちりチェックしたいはず。ということで書いてみました。

内部的には無名のClassXを継承したクラスを作ってやってインスタンス化することでHashをチェックしてるので、classXと同様に使えます。

エラーのときのメッセージは調整した方がデバックなどのしやすさのために良いですが、まだ未調整です。

diff --git a/lib/github_post_reciever/worker/base.rb b/lib/github_post_reciever/worker/base.rb
index 4b1ac05..1a931be 100644
--- a/lib/github_post_reciever/worker/base.rb
+++ b/lib/github_post_reciever/worker/base.rb
@@ -1,9 +1,12 @@
 require 'drb/drb'
 require 'classx'
+require 'classx/validate'
 
 class GitHubPostReciever
   module Worker
     class Base < ClassX
+      include Validate
+
       def run method, json
         raise NoImprementedError
       end
diff --git a/lib/github_post_reciever/worker/irc.rb b/lib/github_post_reciever/worker/irc.rb
index e3aa0ab..ec1d5b0 100644
--- a/lib/github_post_reciever/worker/irc.rb
+++ b/lib/github_post_reciever/worker/irc.rb
@@ -43,13 +43,20 @@ class GitHubPostReciever
       has :template, :is => :ro, :kind_of => String, :required => true
 
       def run method, json
-        json['commits'].reverse.each do |sha, commit|
+        validated_json = validate json do
+          has :commits, :kind_of => Hash, :required => true
+        end
+
+        validated_json.commits.reverse.each do |sha, commit|
           CommitPingBot.new(@host, @port, {
             'nick' => @nick,
             'user' => @user,
             'real' => @real,
           }).run("##{method}", View.new(@template, commit).result)
         end
+      rescue ClassX::InvalidSetterArgumentError => e
+      rescue ClassX::AttrRequiredError => e
+        warn e
       end
     end
   end

実装の方に興味がある方は、http://github.com/walf443/classx/tree/master/lib/classx/validate.rb
をどうぞ。