« AmritaHandler(仮) 20050607版 | メイン | Rubyにannotationを定義するとしたら? »

2005年06月08日 (水)

annotation (a.k.a. metadata) 再考 [テクニカル]

Rubyの attr_* はannotationにほかならない。内部ではメソッド定義でしかないにもかかわらず、「属性」という意味づけが与えられているのだから(RDocなど)。つまり、メソッドに attribute というannotationをつけていることに等しい。

で、Rubyで統一的な annotation を与える書式はどうするのがいいだろうか。やはりRubyでは可読性の高いModuleクラスのメソッドとして定義するべきなのか。

実は暗黙のうちにmetadataを使っているライブラリは多い。

e.g. StrongTyping module:

  attr_accessor_typed String, :foo, :bar

うーん、ダサい。

metadataの意味では、foo, barというメソッドに attribute=>readwrite, type=>String というmetadataを与えていると解釈できる。ならちゃんと並列に同じ記法で書けなきゃ。

Java流なら:


meta_attribute :RW
meta_type String
meta_hoge :key1=>'value1', :key2=>'value2'
def foo
...
end

って感じか。ちょっとダサいかな。。あと意味もわかりにくい。meta_*っていうメソッド名もかぶりそうだし。

もう1つの例。

e.g. ActiveRecord


class Entry < ActiveRecord::Base
def self.table_name; entry; end
belongs_to :blog
belongs_to :author, :foreign_key => 'entry_author_id'
has_one :trackback, :foreign_key => 'trackback_entry_id'
has_many :comments, :foreign_key => 'comment_entry_id'
has_and_belongs_to_many :tbpings, :finder_sql => 'SELECT t.* FROM mt_trackback j, mt_tbping t WHERE t.tbping_tb_id = j.trackback_id AND j.trackback_entry_id= #{entry_id} ORDER BY t.tbping_id'
end

metadata的解釈では、クラスEntryにいろいろmetadataをつけてることになる。Java的アプローチだとこれらはメソッドにつくことになる。さらにオプション項目があればネストしたアノテーションとなる。

メソッドにつけたほうがきめ細かく処理できるはずだが、Rubyではメソッドも自動生成することが多いため、うまい方法がない。必ずdefを書くようにすればできそうだが。(それでもメソッド定義のフックはModule#method_addedで可能だが、クラス定義のフックはどうする?)

Javaで書くとするとこんな感じ?書いたことないから適当だけど。


@Entity
@Table("entry")
public interface Entry {
@ManyToOne
public Blog getBlog();

@ManyToOne
@JoinColumn(name="entry_author_id")
public Author getAuthor();

@OneToOne("trackback")
@JoinColumn(name="trackback_entry_id")
public Trackback getTrackback();

@OneToMany("comment")
@JoinColumn(name="comment_entry_id")
public Set<Comment> getComments();

@ManyToMany("tbping")
@AssociationTable( ... )
public Set<TBPing> getTBPings();
}

投稿者 4bit : 2005年06月08日 19:18 このエントリーを含むはてなブックマーク

トラックバック

このエントリーのトラックバックURL:
http://www.4bit.net/x/mt/mt-tb.cgi/61

コメント

コメントしてください




保存しますか?