Savon/Ruby 问题:初始化客户端 WSDL 时块中的变量上下文
我正在创建一个类来包装 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 和命名空间变量,而不是 @url 和 @namespace 实例变量。
因此,似乎在传入初始化 wsdl 文档的块时,局部变量的上下文被保留,而实例变量的上下文则没有。这是 Ruby 的基本行为吗?
I am creating a class to wrap around a Savon SOAP connection, as follows:
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
This code does not work. The wsdl document that gets initialized has a nil endpoint and a nil namespace.
To make the code work, I have to use the following:
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
Note that when setting up the wsdl.endpoint and wsdl.namespace I am using the local url and namespace variables, not the @url and @namespace instance variables.
So it seems that when passing in the block to initialize the wsdl document, the context of local variables is preserved while the context of instance variables is not. Is this a fundamental behaviour of Ruby?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
幸运的是,这不是“Ruby 的基本行为”,而是与 Savon 如何评估传递给
Savon::Client.new
的块有关。如果您不向块传递任何参数,Savon 将使用 instance_eval with delegate 来评估该块,不幸的是,该块不适用于实例变量,但可以访问局部变量以及类中的方法。
作为替代方案,您可以将 1 到 3 个参数传递给块,并按以下顺序接收可用的对象:
在您的情况下,您只需要第一个对象,因此您的代码将如下所示:
请看一下有关详细信息,请访问 Savon 文档。
Luckily this is not "a fundamental behaviour of Ruby", but related to how Savon evaluates the block passed to
Savon::Client.new
.If you don't pass any arguments to the block, Savon uses instance_eval with delegation to evaluate the block which unfortunately doesn't work with instance variables, but can access local variables and also methods from your class.
As an alternative, you can pass between 1 and 3 arguments to the block and receive the objects available to you in the following order:
In your case, you would only need the first object, so your code would look like:
Please take a look at the documentation for Savon for more information.