如何将数据与 ruby 块一起传递?
How to pass data along with a ruby block?
我正在尝试将一些数据作为块传递给某些外部 API。让它接受额外的参数会很麻烦。如果是javascript
,我可能会这样:
var callback = function() {
// do something
}
callback['__someData'] = options;
someExternalAPI(callback);
Ruby可以吗?或者我应该如何将一些数据与块相关联?
不确定对问题的编辑是否正确。首先,如果可能的话,我想特别传递一些数据和一个块。不确定是否是。在 ruby
中,唯一的方法可能是将一些数据作为块传递。
此外,here 可能是一些有用的信息。
好吧,展示一下全貌大概是有道理的。我正在努力使 webmock
适应我的需要。我有一个函数,它检查请求的参数(是 POST
或 GET
的参数)是否符合指定的条件:
def check_params params, options
options.all? do |k,v|
return true unless k.is_a? String
case v
when Hash
return false unless params[k]
int_methods = ['<', '<=', '>', '>=']
v1 = int_methods.include?(v.first[0]) ? params[k].to_i : params[k]
v2 = int_methods.include?(v.first[0]) \
? v.first[1].to_i : v.first[1].to_s
v1.send(v.first[0], v2)
when TrueClass, FalseClass
v ^ ! params.key?(k)
else
params[k] == v.to_s
end
end
end
它并不完美,但现在足以满足我的特殊需求。我这样称呼它:
stub_request(:post, 'http://example.com/')
.with { |request|
check_params Rack::Utils.parse_query(request.body), options
}
而且通常我看不出输出 with block
条件的明智方法。但在我的特殊情况下,可以只输出 options
散列。而不是这个:
registered request stubs:
stub_request(:post, "http://example.com")
拥有这个:
stub_request(:post, "http://example.com").
with(block: {"year"=>2015})
这就是我想要做的。
好吧,我最后这样做了:
p = Proc.new {}
p.class.module_eval { attr_accessor :__options }
p.__options = {a: 1}
# ...
pp p.__options
或者更具体地说:
def mk_block_cond options, &block_cond
options = options.select { |k,v| ! k.is_a?(Symbol) }
return block_cond if options.empty?
block_cond.class.module_eval { attr_accessor :__options }
block_cond.__options = options
block_cond
end
module WebMock
class RequestPattern
attr_reader :with_block
end
end
module StubRequestSnippetExtensions
def to_s(with_response = true)
request_pattern = @request_stub.request_pattern
string = "stub_request(:#{request_pattern.method_pattern.to_s},"
string << " \"#{request_pattern.uri_pattern.to_s}\")"
with = ""
if (request_pattern.body_pattern)
with << ":body => #{request_pattern.body_pattern.to_s}"
end
if (request_pattern.headers_pattern)
with << ",\n " unless with.empty?
with << ":headers => #{request_pattern.headers_pattern.to_s}"
end
if request_pattern.with_block \
&& request_pattern.with_block.respond_to?('__options') \
&& request_pattern.with_block.__options
with << ",\n " unless with.empty?
with << "block: #{request_pattern.with_block.__options}"
end
string << ".\n with(#{with})" unless with.empty?
if with_response
string << ".\n to_return(:status => 200, :body => \"\", :headers => {})"
end
string
end
end
module WebMock
class StubRequestSnippet
prepend StubRequestSnippetExtensions
end
end
module RequestPatternExtensions
def to_s
string = "#{@method_pattern.to_s.upcase}"
string << " #{@uri_pattern.to_s}"
string << " with body #{@body_pattern.to_s}" if @body_pattern
string << " with headers #{@headers_pattern.to_s}" if @headers_pattern
if @with_block
if @with_block.respond_to?('__options') \
&& @with_block.__options
string << " with block: %s" % @with_block.__options.inspect
else
string << " with given block"
end
end
string
end
end
module WebMock
class RequestPattern
prepend RequestPatternExtensions
end
end
现在我用这种方式存根请求:
stub_request(:post, 'http://example.com/')
.with &mk_block_cond(options) { |request|
check_params Rack::Utils.parse_query(request.body), options
}
P.S. github
issue
我正在尝试将一些数据作为块传递给某些外部 API。让它接受额外的参数会很麻烦。如果是javascript
,我可能会这样:
var callback = function() {
// do something
}
callback['__someData'] = options;
someExternalAPI(callback);
Ruby可以吗?或者我应该如何将一些数据与块相关联?
不确定对问题的编辑是否正确。首先,如果可能的话,我想特别传递一些数据和一个块。不确定是否是。在 ruby
中,唯一的方法可能是将一些数据作为块传递。
此外,here 可能是一些有用的信息。
好吧,展示一下全貌大概是有道理的。我正在努力使 webmock
适应我的需要。我有一个函数,它检查请求的参数(是 POST
或 GET
的参数)是否符合指定的条件:
def check_params params, options
options.all? do |k,v|
return true unless k.is_a? String
case v
when Hash
return false unless params[k]
int_methods = ['<', '<=', '>', '>=']
v1 = int_methods.include?(v.first[0]) ? params[k].to_i : params[k]
v2 = int_methods.include?(v.first[0]) \
? v.first[1].to_i : v.first[1].to_s
v1.send(v.first[0], v2)
when TrueClass, FalseClass
v ^ ! params.key?(k)
else
params[k] == v.to_s
end
end
end
它并不完美,但现在足以满足我的特殊需求。我这样称呼它:
stub_request(:post, 'http://example.com/')
.with { |request|
check_params Rack::Utils.parse_query(request.body), options
}
而且通常我看不出输出 with block
条件的明智方法。但在我的特殊情况下,可以只输出 options
散列。而不是这个:
registered request stubs:
stub_request(:post, "http://example.com")
拥有这个:
stub_request(:post, "http://example.com").
with(block: {"year"=>2015})
这就是我想要做的。
好吧,我最后这样做了:
p = Proc.new {}
p.class.module_eval { attr_accessor :__options }
p.__options = {a: 1}
# ...
pp p.__options
或者更具体地说:
def mk_block_cond options, &block_cond
options = options.select { |k,v| ! k.is_a?(Symbol) }
return block_cond if options.empty?
block_cond.class.module_eval { attr_accessor :__options }
block_cond.__options = options
block_cond
end
module WebMock
class RequestPattern
attr_reader :with_block
end
end
module StubRequestSnippetExtensions
def to_s(with_response = true)
request_pattern = @request_stub.request_pattern
string = "stub_request(:#{request_pattern.method_pattern.to_s},"
string << " \"#{request_pattern.uri_pattern.to_s}\")"
with = ""
if (request_pattern.body_pattern)
with << ":body => #{request_pattern.body_pattern.to_s}"
end
if (request_pattern.headers_pattern)
with << ",\n " unless with.empty?
with << ":headers => #{request_pattern.headers_pattern.to_s}"
end
if request_pattern.with_block \
&& request_pattern.with_block.respond_to?('__options') \
&& request_pattern.with_block.__options
with << ",\n " unless with.empty?
with << "block: #{request_pattern.with_block.__options}"
end
string << ".\n with(#{with})" unless with.empty?
if with_response
string << ".\n to_return(:status => 200, :body => \"\", :headers => {})"
end
string
end
end
module WebMock
class StubRequestSnippet
prepend StubRequestSnippetExtensions
end
end
module RequestPatternExtensions
def to_s
string = "#{@method_pattern.to_s.upcase}"
string << " #{@uri_pattern.to_s}"
string << " with body #{@body_pattern.to_s}" if @body_pattern
string << " with headers #{@headers_pattern.to_s}" if @headers_pattern
if @with_block
if @with_block.respond_to?('__options') \
&& @with_block.__options
string << " with block: %s" % @with_block.__options.inspect
else
string << " with given block"
end
end
string
end
end
module WebMock
class RequestPattern
prepend RequestPatternExtensions
end
end
现在我用这种方式存根请求:
stub_request(:post, 'http://example.com/')
.with &mk_block_cond(options) { |request|
check_params Rack::Utils.parse_query(request.body), options
}
P.S. github
issue