首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >YARD⇒如何基于YARD插件中的一条DSL语句向多个方法描述添加自定义输出

YARD⇒如何基于YARD插件中的一条DSL语句向多个方法描述添加自定义输出
EN

Stack Overflow用户
提问于 2013-03-11 19:03:55
回答 1查看 347关注 0票数 0

我在为以下DSL编写YARD插件时遇到了问题:

代码语言:javascript
复制
class MyClass
  my_dsl :do_it, :do_other
  def do_it
    # do it
  end
  def do_other
    # do other
  end
  def do_unrelated
    # do unrelated
  end
end

现在,我想向这些方法的文档片段添加注释,它们受到DSL my_dsl的“影响”。在my_dsl处理程序中,作用域是完全不同的(我不想添加一些新的文档,我想扩展已经存在的方法)。

因此,我决定在MyDSLHandler#process中使用Proxy代码对象来标记所需的方法,以便将来进行延迟的后处理(这将在def do_it ; … ; end的内置MethodHandler中发生)。看起来是这样的:

代码语言:javascript
复制
class MyDSLHandler < YARD::Handlers::Ruby::DSLHandler
  handles method_call(:my_dsl)
  namespace_only

  def process
    statement.parameters.each { |astnode|
      mthd = astnode.jump(:string_content).source if astnode.respond_to? :jump
      obj = YARD::CodeObjects::Proxy.new(namespace, "\##{mthd}", :method)
      register(obj)
      obj[:my_dsl_params] << {
        name: mthd,
        file: statement.file, line: statement.line # I need this!
      }
    }
  end
end

现在的问题是,Proxy对象是从普通的Object派生的,而不是从YARD::CodeObjects::Base派生的,因此没有定义[]=方法:

代码语言:javascript
复制
[warn]: Load Order / Name Resolution Problem on MyClass#do_it:
[warn]: -
[warn]: Something is trying to call [] on object MyClass#do_it before it has been recognized.
[warn]: This error usually means that you need to modify the order in which you parse files
[warn]: so that MyClass#do_it is parsed before methods or other objects attempt to access it.
[warn]: -
[warn]: YARD will recover from this error and continue to parse but you *may* have problems
[warn]: with your generated documentation. You should probably fix this.
[warn]: -
[error]: Unhandled exception in Yard::Handlers::MyDSLHandler:
[error]:   in `example_mydsl.rb`:5:

    5: my_dsl :do_it, :do_other

[error]: ProxyMethodError: Proxy cannot call method #[] on object 'MyClass#do_it'

我应该如何将当前上下文中的一些值存储到Proxy对象中,以便它们在对象实例化期间可用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-13 22:00:21

好吧,我解决了这个问题。

这里不应该使用ProxyCodeObject有一个非常特殊的特性:它们是“静默”单例。因此,由于您已经通过CodeObject.new定义了一个对象,所有即将对同一对象上的new的调用(根据Registry)都将被重新映射到现有的调用。

因此,在我的示例中,我简单地创建了MethodObject

代码语言:javascript
复制
m = "#{astnode.jump(:string_content).source[1..-1]}";
obj = YARD::CodeObjects::MethodObject.new(namespace, "#{m}")

然后我在新创建的对象上做我想做的事情:

代码语言:javascript
复制
obj.my_dsl_params = { :win => true, :mthd => "#{m}", … }

方法定义解析中的对象会用它自己的属性来解析( merge )这些属性。唯一需要的就是向register(obj)注册一个对象,或者从process方法返回该对象以进行系统注册。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15336962

复制
相关文章

相似问题

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