1

次のように、SavonSOAP接続をラップアラウンドするクラスを作成しています。

class SOAPConnection

  attr_reader :url, :namespace

  def initialize(url, namespace)
    @url = url
    @namespace = namespace

    @client = Savon::Client.new do
      wsdl.endpoint = @url
      wsdl.namespace = @namespace
    end
  end

end

このコードは機能しません。初期化されるwsdlドキュメントには、nilエンドポイントとnil名前空間があります。

コードを機能させるには、次を使用する必要があります。

class SOAPConnection

  attr_reader :url, :namespace

  def initialize(url, namespace)
    @url = url
    @namespace = namespace

    @client = Savon::Client.new do
      wsdl.endpoint = url          # <=== use local variable
      wsdl.namespace = namespace   # <=== use local variable
    end
  end

end

wsdl.endpointとwsdl.namespaceを設定するときは、@ urlと@namespaceのインスタンス変数ではなく、ローカルのurlと名前空間の変数を使用していることに注意してください。

したがって、ブロックを渡してwsdlドキュメントを初期化する場合、ローカル変数のコンテキストは保持されますが、インスタンス変数のコンテキストは保持されないようです。これはRubyの基本的な動作ですか?

4

1 に答える 1

1

幸い、これは「Rubyの基本的な動作」ではありませんが、Savonがに渡されたブロックを評価する方法に関連していSavon::Client.newます。

ブロックに引数を渡さない場合、Savonは委任とともにinstance_evalを使用してブロックを評価します。これは残念ながらインスタンス変数では機能しませんが、ローカル変数やクラスのメソッドにアクセスできます。

別の方法として、1〜3個の引数をブロックに渡し、次の順序で使用可能なオブジェクトを受け取ることができます。

[wsdl, http, wsse]

あなたの場合、必要なのは最初のオブジェクトだけなので、コードは次のようになります。

@client = Savon::Client.new do |wsdl|    # <= one argument
  wsdl.endpoint = @url
  wsdl.namespace = @namespace
end

詳細については、Savonのドキュメントを参照してください。

于 2011-03-23T14:32:50.220 に答える