Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@matsukaz
Last active August 10, 2021 08:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matsukaz/06bd42aca25cba9dc569bc5aaaf3374f to your computer and use it in GitHub Desktop.
Save matsukaz/06bd42aca25cba9dc569bc5aaaf3374f to your computer and use it in GitHub Desktop.
Rubyでアノテーションを実装 / Implementing java-like annotations in ruby
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
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
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}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment