Savon / Ruby问题:初始化Client WSDL时块中的变量上下文

时间:2011-03-21 14:24:58

标签: ruby savon

我正在创建一个包装Savon SOAP连接的类,如下所示:

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 个答案:

答案 0 :(得分:1)

幸运的是,这不是“Ruby的基本行为”,而是与Savon如何评估传递给Savon::Client.new的块有关。

如果你没有向块传递任何参数,Savon使用instance_eval with delegation来评估不幸与实例变量无关的块,但可以访问本地变量以及类中的方法。

作为替代方案,您可以在块中传递1到3个参数,并按以下顺序接收可用的对象:

[wsdl, http, wsse]

在您的情况下,您只需要第一个对象,因此您的代码将如下所示:

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

请查看documentation for Savon了解详情。