Вопрос Savon / Ruby: переменный контекст в блоке при инициализации Client WSDL - PullRequest
1 голос
/ 21 марта 2011

Я создаю класс для обертывания SOAP-соединения Savon следующим образом:

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 и @namespace.

Таким образом, кажется, что при передаче блока для инициализации документа wsdl контекстлокальные переменные сохраняются, а контекст переменных экземпляра - нет.Это фундаментальное поведение Ruby?

1 Ответ

1 голос
/ 23 марта 2011

К счастью, это не "фундаментальное поведение 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 для получения дополнительной информации.

...