首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用元编程向Ruby语言添加文档字符串

使用元编程向Ruby语言添加文档字符串
EN

Stack Overflow用户
提问于 2013-08-11 14:54:02
回答 2查看 308关注 0票数 1

我想使用元编程将docstring特性引入Ruby语言。

下面是我到目前为止编写的代码的早期原型:

代码语言:javascript
复制
module Docstrings
  def doc(docstring)
    @docstrings ||= {}
    if docstring.is_a? String
      # Ruby 2.0 trick to get a caller of the method
      method_caller = caller_locations(1,1)[0].label.to_sym

      @docstrings[method_caller] ||= docstring
    else
      @docstrings[docstring]
    end
  end
end

# lets include it temporarily to see how it works
include Docstrings

class Method
   include Docstrings
end

doc "Hello"
puts doc :"<main>" # => "Hello"

它起作用了。但是,可悲的是:

代码语言:javascript
复制
def square(x)
  doc """This method returns square of x"""

  x * x
end

doc(:square) # => nil

这不像我预料的那样有效。

代码语言:javascript
复制
square(2)
doc(:square) # => """This method returns square of x"""

它只会在调用至少1次方法square时添加docstring,这是显而易见的。

我的问题是,是否有可能以一种将更多的docstring附加到方法,而不是调用该方法的方式实现?我在寻找提示而不是解决方案,请告诉我应该在哪里查找:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-11 16:47:57

这似乎是可行的:(尽管,它并不是真正的元编程,只是一个黑客)。

假设你想要这个:

代码语言:javascript
复制
  def add_these(a, b)
    doc "This function adds two numbers"
    a + b
  end

whatsthedocdoc?(:add_these) # => "This function adds two numbers"

class Object
  def whatsthedocdoc?(method)
    meth = method(method.to_sym)
    sours = meth.source
    puts sours.lines.grep(/doc/).join.gsub(/doc|\"/, "").strip
  end
end

但这并不是那么简单。上面的片段假设方法是在main对象空间中定义的。让我们考虑一下这个例子:

代码语言:javascript
复制
class A
  def add_these(a, b)
    doc "This method adds two numbers."
  end
end

在本例中,whatsthedocdoc?方法中的代码应该更改为:

代码语言:javascript
复制
def whatsthedocdoc?(string)
  receiver, meth = string.split(/\#/)
  meth_instance = receiver.method(meth.to_sym)
  sours = meth_instance.source
  # rest is the same as above
end

文档可以这样查看:

代码语言:javascript
复制
whatsthedocdoc?("A#add_these") # => This method adds two numbers.

现在不太整洁了,是吗?

噢!还有另一种边缘情况:类方法

代码语言:javascript
复制
class A
  def self.add_these(a, b)
    doc "This too, adds two numbers"
  end
end

你知道这个主意..。

票数 2
EN

Stack Overflow用户

发布于 2013-08-11 16:42:59

使用红宝石钩,我们可以拦截方法的定义。因此,这个解决方案可以工作,但是doc()必须在方法def之前定义:

代码语言:javascript
复制
class Object

    def self.method_added(s)
        @docString||={}
        if defined?(@lastdoc)&& @lastdoc!=""
            @docString[s]=@lastdoc
            @lastdoc=""
        else
            @docString[s]="!uncommented !"
        end
    end
    def self.defdoc(s)
        @lastdoc=s
    end
    ################ report
    def self.get_docs()
        @docString||={}
        puts "Doc for #{self.to_s} is : \n"
        @docString.each  {|k,v|puts " #{k} : #{v}\n"}
        puts "end for #{self.to_s}\n"
    end
    def get_docs(*klass)
        klass.each {|c| c.get_docs()}
    end
end
################# exemple :
class Foo
    defdoc "toto() defined"
    def toto ;end
    def titi ;end
    defdoc "tutu() defined"
    def tutu ;end
    def tata ;end
end
class Fee < Foo
end

get_docs Foo,Fee

这意味着:

代码语言:javascript
复制
Doc for Foo is :
 toto : toto() defined
 titi : !uncommented !
 tutu : tutu() defined
 tata : !uncommented !
end for Foo
Doc for Fee is :
end for Fee
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18173192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档