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

时间:2010-07-01 11:49:57

标签: ruby annotations

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

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

3 个答案:

答案 0 :(得分:29)

这是几周前改编自a piece of code I wrote in an answer to another question的,虽然它当然不是原创的。毕竟,这个 是一个众所周知的Ruby成语,至少从rakes的{​​{1}}方法开始,它已经使用多年了。

desc

这是一个小例子:

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

当然,如果没有测试套件,Ruby代码就不会完整:

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

答案 1 :(得分:2)

这是预期用途:

首先注释一个类。

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")

答案 2 :(得分:2)

我的要求是

  

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

现在我不知道这只是我还是将所有这些方法的描述与他们的名字存储在数据库中的新表中“超级名人”

  

答案是 - “注释”

我是这样做的 -

  1. cibercitizen1
  2. 给出的模块注释
  3. 包含模块并激活所需类别中的功能的代码
  4. 班级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的视图中通过instance_methods集合的注释属性哈希显示给定描述(仅限方法名称)。
    2. 查看methods_list.html.erb

       <html>
       <head>
       </head>
       <body> 
       <% default_description = "Description not specified" %>
        <% Abc.instance_methods.each do |method| %>
           <span style="float:right">
           <%= (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) %>
           </span>
      
         <% end %> 
       </body>  
      </html>
      

      希望它有所帮助!

相关问题