LoginSignup
12
10

More than 5 years have passed since last update.

Rubyでアノテーションを実装してみた

Posted at

Rubyでアノテーション

RubyでJava的なアノテーションが使いたくなったので実装してみました。
参考にしたのは以下の質問に対する回答。

How to simulate Java-like annotations in Ruby?
http://stackoverflow.com/questions/3157426/how-to-simulate-java-like-annotations-in-ruby

そのまんまだとインスタンスメソッドにしか対応できなかったので、クラスメソッド含めアノテーションを付与できるようにしてみました。

使い方

メソッドに対して_で始まるアノテーションを記述する。

sample.rb
require './annotations'

class Sample
  annotate!

  _label_only
  def instance_method1; end

  _with_args arg1: 'val1', arg2: 1
  def instance_method2; end

  _label_only
  def self.class_method1; end

  _with_args arg1: 'val2', arg2: 2
  def self.class_method2; end
end

クラス名.annotations()でメソッド名をシンボルで指定することで、メソッドに追加されたアノテーションを取得できる。引数も指定可能。
クラスメソッドとインスタンスメソッドで同名が使われるとアノテーションが混在してしまうので、インスタンスメソッドのシンボルはメソッド名の頭に_を付与することにした。

test.rb
require './sample'

p Sample.annotations(:_instance_method1)  # {:label_only=>[]}
p Sample.annotations(:_instance_method2)  # {:with_args=>{:arg1=>"val1", :arg2=>1}}
p Sample.annotations(:class_method1)      # {:label_only=>[]}
p Sample.annotations(:class_method2)      # {:with_args=>{:arg1=>"val2", :arg2=>2}}

annotations.rbの実装

annotations.rb
module Annotations
  @@__last_annotation__ = nil

  def annotations(meth=nil)
    return @@__annotations__[meth] if meth
    @@__annotations__
  end

  private

  def singleton_method_added(m)
    (@@__annotations__ ||= {})[m] = @@__last_annotation__ if @@__last_annotation__
    @@__last_annotation__ = nil
    super
  end

  def method_added(m)
    (@@__annotations__ ||= {})["_#{m.to_s}".to_sym] = @@__last_annotation__ if @@__last_annotation__
    @@__last_annotation__ = nil
    super
  end

  def method_missing(meth, *args)
    return super unless /^\_/ =~ meth
    @@__last_annotation__ ||= {}
    @@__last_annotation__[meth[1..-1].to_sym] = args.size == 1 ? args.first : args
  end
end

class Module
  private

  def annotate!
    extend Annotations
  end
end

Gistにも投稿しました。
https://gist.github.com/matsukaz/06bd42aca25cba9dc569bc5aaaf3374f

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10