Arn*_*met 4 ruby ruby-on-rails code-comments
有没有办法以编程方式访问方法注释?或属性评论?
我想用它作为文档中方法的描述,我不希望它是静态的或用rdoc或等效的方法生成.
以下是Ruby类的示例:
Class MyClass
##
# This method tries over and over until it is tired
def go_go_go(thing_to_try, tries = 10) # :args: thing_to_try
puts thing_to_try
go_go_go thing_to_try, tries - 1
end
end
Run Code Online (Sandbox Code Playgroud)
基本上,我希望能够做到以下几点:
get_comment MyClass.gogogo # => This method tries over and over until it is tired
Run Code Online (Sandbox Code Playgroud)
Jör*_*tag 13
不,你不能这样做.
评论的全部意义在于它们不属于该计划的一部分!如果你想要一个属于你的程序的字符串,只需使用一个字符串.
在大多数Ruby实现中,注释已经在词法分析器中被丢弃,这意味着它们甚至不会到达解析器,更不用说解释器或编译器了.在代码运行时,注释很快就消失了......事实上,在使用编译器的Rubinius或YARV这样的实现中,根本没有办法将注释存储在已编译的可执行文件中,所以即使它们没有被抛出在词法分析器或解析器之外,仍然没有办法将它们传达给运行时.
所以,你唯一的机会就是解析Ruby源文件来提取注释.但是,就像我上面提到的那样,你不能只使用任何解析器,因为大多数现有的解析器会抛出注释.(这又是整点的意见,所以没有什么不对的解析器扔掉.)有,但是,红宝石解析器其保留意见,最显着的工具,如RDoc的或者YARD所使用的那些.
YARD特别有趣,因为它还包含一个查询引擎,它允许您根据类名,方法名,YARD标记,API版本,类型签名等强大的谓词搜索和过滤文档.
但是,如果你做的最终使用的RDoc或院子里解析,那么为什么不首先使用它们?
或者,就像我上面建议的那样,如果你想要字符串,只需使用字符串:
module MethodAddedHook
private
def method_added(meth)
(@__doc__ ||= {})[meth] = @__last_doc__ if @__last_doc__
@__last_doc__ = nil
super
end
end
class Module
private
prepend MethodAddedHook
def doc(meth=nil, str)
return @__doc__[meth] = str if meth
@__last_doc__ = str
end
def defdoc(meth, doc, &block)
@__doc__[meth] = doc
define_method(meth, &block)
end
end
Run Code Online (Sandbox Code Playgroud)
这给了我们一个方法Module#doc,我们可以用它来记录已经存在的方法,方法是用方法的名称和docstring来调用它,或者你可以用它来记录你定义的下一个方法.它通过将docstring存储在临时实例变量中,然后定义一个method_added查看该实例变量的钩子并将其内容存储在文档哈希中来实现.
还有Module#defdoc一种方法可以一次定义和记录该方法.
module Kernel
private
def get_doc(klass, meth)
klass.instance_variable_get(:@__doc__)[meth]
end
end
Run Code Online (Sandbox Code Playgroud)
这是Kernel#get_doc获取文档nil的方法(或者如果方法没有记录).
class MyClass
doc 'This method tries over and over until it is tired'
def go_go_go(thing_to_try, tries = 10)
puts thing_to_try
go_go_go thing_to_try, tries - 1
end
def some_other_meth; end # Oops, I forgot to document it!
# No problem:
doc :some_other_meth, 'Does some other things'
defdoc(:yet_another_method, 'This method also does something') do |a, b, c|
p a, b, c
end
end
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到记录方法的三种不同方法.
哦,它有效:
require 'test/unit'
class TestDocstrings < Test::Unit::TestCase
def test_that_myclass_gogogo_has_a_docstring
doc = 'This method tries over and over until it is tired'
assert_equal doc, get_doc(MyClass, :go_go_go)
end
def test_that_myclass_some_other_meth_has_a_docstring
doc = 'Does some other things'
assert_equal doc, get_doc(MyClass, :some_other_meth)
end
def test_that_myclass_yet_another_method_has_a_docstring
doc = 'This method also does something'
assert_equal doc, get_doc(MyClass, :yet_another_method)
end
def test_that_undocumented_methods_return_nil
assert_nil get_doc(MyClass, :does_not_exist)
end
end
Run Code Online (Sandbox Code Playgroud)
注意:这非常hacky.例如,没有锁定,因此如果两个线程同时为同一个类定义方法,则文档可能会搞砸.(即:docstring可能归因于错误的方法或迷路.)
我认为,rake做实质上是一样的,其desc方法和代码库很多比这更好的测试,所以如果你打算在生产中使用它,我会偷吉姆的代码,而不是我的.
| 归档时间: |
|
| 查看次数: |
2021 次 |
| 最近记录: |