2007-02-24
■ [ruby] Webサービス経由で足し算を行うライブラリ:jitor-int.rb
LiveCoding中に氏久さんが作ったIntというサービスを利用するライブラリを作ってみました。
Intは整数の演算を行うWebサービスで、例えば http://int.jitor.net/add/3/4 にアクセスすると"7"と書かれたページが 得られます。
さて、これをRubyから使うにはどういうAPIが良いでしょうか?JitorInt.add(3,4) とか? いやいや、こんな長いのは覚えにくいし、足し算を行うのにこんなのをいちいち書いてられませんよね。 「良くつかうものは短い名前にする」という原則に従えば、ここは組込みのFixnum#+をオーバーライドするしか ありません。
というわけで、jitor-int.rbです。
require 'open-uri' class Fixnum def use_orig alias :+ :add_orig result = yield alias :+ :add_jitor result end def add_jitor(other) url = "http://int.jitor.net/add/#{self}/#{other}" puts "accessing to #{url}..." result = use_orig{ open(url).read } p result result.to_i end alias :add_orig :+ alias :+ :add_jitor end
これを使うと、例えば
require 'jitor-int' p 1 + 2 + 3
のようなスクリプトが
accessing to http://int.jitor.net/add/1/2... "3" accessing to http://int.jitor.net/add/3/3... "6" 6
のような感じで動きます。require 'jitor-int' と書くだけで、Webサービス経由で足し算できるようになります。簡単ですね :-)
このライブラリがあれば、突然Rubyで足し算ができなくなっても安心!…と言いたいところなのですが、 実はopen-uriが中で Fixnum#+ を使っているため組込みの「+」は残念ながら必要です。
また普通にオーバーライド しただけでは無限再帰になってしまうので、Webにアクセスするところだけ + の定義を組込みのものに戻しています。
おまけ
「-」「*」「%」にも対応したバージョンを以下に貼っておきます。(「/」がないのは仕様です。)
require 'open-uri' class Fixnum SYMS = { :+ => :add, :- => :sub, :* => :multi, :% => :mod } def switch_method(sym, method) self.class.instance_eval do alias_method sym, method end end def use_orig SYMS.each{|sym, name| switch_method(sym, "#{sym}_orig")} result = yield SYMS.each{|sym, name| switch_method(sym, name)} result end def jitor(type,a,b) url = "http://int.jitor.net/#{type}/#{a}/#{b}" puts "accessing to #{url}..." result = use_orig{ open(url).read } p result result.to_i end SYMS.each do |sym, name| define_method name do |other| jitor(name, self, other) end alias_method "#{sym}_orig", sym alias_method sym, name end end