如何在Ruby中模拟类似Java的注释?

如何在ruby中模拟类似Java的注释?

(我们将得到答案,概括http://bens.me.uk/2009/java-style-annotations-in-ruby )

这是根据我几周前在另一个问题的答案中写的一段代码改编的,尽管它当然不是原创的。 毕竟,这一个众所周知的Ruby成语,已经使用了很多年,至少从rakesdesc方法开始。

 module Annotations def annotations(meth=nil) return @__annotations__[meth] if meth @__annotations__ end private def method_added(m) (@__annotations__ ||= {})[m] = @__last_annotation__ if @__last_annotation__ @__last_annotation__ = nil super end def method_missing(meth, *args) return super unless /\A_/ =~ 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 

这是一个小例子:

 class A annotate! _hello color: 'red', ancho: 23 _goodbye color: 'green', alto: -123 _foobar color: 'blew' def m1; end def m2; end _foobar color: 'cyan' def m3; end end 

如果没有测试套件,当然没有Ruby代码是完整的:

 require 'test/unit' class TestAnnotations < Test::Unit::TestCase def test_that_m1_is_annotated_with_hello_and_has_value_red assert_equal 'red', A.annotations(:m1)[:hello][:color] end def test_that_m3_is_annotated_with_foobar_and_has_value_cyan assert_equal 'cyan', A.annotations[:m3][:foobar][:color] end def test_that_m1_is_annotated_with_goodbye assert A.annotations[:m1][:goodbye] end def test_that_all_annotations_are_there annotations = { m1: { hello: { color: 'red', ancho: 23 }, goodbye: { color: 'green', alto: -123 }, foobar: { color: 'blew' } }, m3: { foobar: { color: 'cyan' } } } assert_equal annotations, A.annotations end end 

这是预期用途:

首先,您要注释一个类。

 class A extend Annotations extend MyAnnotations create_annotation("_foobar") _hello({:color=>'red', :ancho=>23}) _goodbye({:color=>'green', :alto=>-123}) _foobar({:color=>'blew'}) def m1 end def m2 end _foobar({:color=>'cyan'}) def m3 end end 

然后你想检查A的这样的传单:

 anots = A.annotations puts anots.keys puts anots[:m1][:_hello][:color] puts anots[:m3][:_foobar][:color] puts anots[:m1].key?(:_goodbye) puts "---------------" anots.each do |met| # each annotated method puts "-- annotated method --" puts met[0] # method name met[1].each do |a| # each annotation for the method puts "-> " + a[0].to_s # annotation name a[1].each do |par| # each pair: key-value puts " key=" + par[0].to_s + " value=" + par[1].to_s end end end 

好。 为此,您将需要此模块

 module Annotations @@annotation_list = {} @@pending = {} def method_added(met_sym) #puts "-> adding " + met_sym.to_s + " to class + self.to_s if @@pending.size > 0 #puts met_sym.to_s + " is annotated " @@annotation_list[met_sym] = @@pending #puts @@annotation_list else #puts met_sym.to_s + " is not annotated " end @@pending = {} end def annotate_method(a,b) @@pending[a] = b end def create_annotation(anot_sym) code = "def #{anot_sym.to_s}(val) annotate_method( :#{anot_sym} ,val) end" instance_eval code end def annotations return @@annotation_list end end 

并且您可以在您的模块中定义一组注释:

 module MyAnnotations def _goodbye(val) annotate_method(:_goodbye, val) end def _hello(val) annotate_method(:_hello, val) end end 

或者将它们定义到您正在注释的类中:

 create_annotation("_foobar") 

我的要求是

在页面上,我显示了一个类ABC的所有instance_methods列表,每个方法也应该有一行描述

现在我不知道它是否只是我或者将所有这些方法的描述与他们的名字一起存储在DB中的新表中“Super LAME”

答案是 – “注释”

我是这样做的 –

  1. cibercitizen1给出的模块注释
  2. 代码包含模块并激活所需类中的function

类abc.rb

 class Abc extend Annotations create_annotation("_annotation") _annotation({:description=>"Info e-mail address"}) def info_email APP_CONFIG['info_email'] end _annotation({:description=>"Location of order"}) def location unless self.order.blank? @location ||= self.order.location.description end end 
  1. 在有权访问类Abc的视图中,通过实例_methods集合的注释属性哈希显示给定描述(仅限,不是方法名称)的代码。

查看methods_list.html.erb

      <% default_description = "Description not specified" %> <% Abc.instance_methods.each do |method| %>  <%= (Abc.annotations[method.to_sym].present? ? (Abc.annotations[method.to_sym][:_annotation][:description].blank? ? default_description : Abc.annotations[method.to_sym][:_annotation][:description]) : default_description) %>  <% end %>   

希望能帮助到你!