simple-rss.rbのカスタマイズ
id:omochist:20060922:simplerss
の続き.
descriptionでNoMethodErrorが発生したらrescueしてtaglineを呼ぶ,とかするのは楽だろうけど,itemの方はnilが返ってきておるし….どーすりゃ良いんでしょうね.
って書いたけれど,この辺りはなんとか解決ができそう.
NoMethodErrorの対処
もしタグtaglineを追加したいのであれば,まずクラス変数feed_tagsにSymbolのtaglineを追加し,次にObject#method_missingをオーバーライドすることで対処できる.
@@feed_tags = [ :tagline, (略)] def method_missing(name, *arguments) if name.to_s =~ /description/ self.send('tagline') else super end end
こんな感じのを書くと,インタフェースを統一できるよね.RDFでもAtomでも,rss.descriptionって呼べばそのフィードの概要を得られるということで.本格的に使うのなら,もっと条件分岐を増やすべきだろうけど.
itemの要素がnilの時の対処
以下の部分を変更する.
def parse (略) # RSS items' title, link, and description (略) def item.method_missing(name, *args) self[name] end
の一番最後の行を,
def item.method_missing(name, *args) if name.to_s =~ /description/ && self[name].nil? self[:summary] else self[name] end end
にするとか.こちらもコレでは不十分なので,もっと色々増やした方が良いのかな.でももっと良いのは,itemはHashなんだけれど,いっそItemクラスを作っちゃってmethod_missingを定義した方が良いと思うんだよね.
class Item < Hash # Hashを継承 def method_missing(name, *args) if name.to_s =~ /description/ && self[name].nil? self[:summary] else self[name] end end end
これぐらいしておけば,item要素を追加して幾たびにmethod_missingを定義しなくて済むし.なので,結局はsimple-rss.rbに上のItemの定義を追加して,
def parse (略) # RSS items' title, link, and description @source.scan( %r{(長いので略)}mi ) do |match| item = Item.new # Hash.newをItem.newに @@item_tags.each do |tag| if match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi nil elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)/\s*>}mi nil end item[clean_tag(tag)] = clean_content(tag, $2, $3) if $2 || $3 end # def item.method_missing(name, args*) self[name] end を削除 @items << item end
にすれば良いかな.
だれか,もっとガッチリ作り直してくれないかしら.