0

次の DSL の YARD プラグインの作成に問題があります。

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は、スコープはまったく異なります (新しいドキュメントを追加したくありません。既存のメソッドを拡張したいのです。)

そのため、内部でProxyコード オブジェクトを使用MyDSLHandler#processして、後で後処理を遅らせるために必要なメソッドをマークすることにしました (これは、組み込みのMethodHandleron内で発生しdef do_it ; … ; endます)。

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プレーンから派生しているため、メソッドが定義されていないことです。ObjectYARD::CodeObjects::Base[]=

[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オブジェクトにいくつかの値を保存するにはどうすればよいですか?

4

1 に答える 1

1

なるほど、解決できました。

ここの使用はProxy想定されていません。s にはかなり特殊な点があります。CodeObjectそれらは「サイレント」なシングルトンです。したがって、 を介してオブジェクトを定義したため、同じオブジェクトに対するCodeObject.new今後のすべての呼び出しnew( に従ってRegistry) は、既存のオブジェクトに再マップされます。

したがって、私の場合、単に作成しますMethodObject

m = "#{astnode.jump(:string_content).source[1..-1]}";
obj = YARD::CodeObjects::MethodObject.new(namespace, "#{m}")

次に、新しく作成されたオブジェクトで必要なことを行います。

obj.my_dsl_params = { :win => true, :mthd => "#{m}", … }

メソッド定義解析内のオブジェクトはmerge、これらのプロパティを独自のものにします。必要なのは、オブジェクトを登録するか、システム登録用のメソッドregister(obj)からオブジェクトを返すことだけです。process

于 2013-03-13T14:00:21.077 に答える