为什么减去两个相同数组的 ruby 语句无法通过 .empty?测试?

Why does this ruby statement, which subtracts two identical arrays, fail the .empty? test?

在此代码段中(来自 https://github.com/bitfinexcom/bitfinex-api-rb/blob/master/lib/bitfinex/connection.rb 的第 19 行 - 这也是包含 check_params 方法定义的 class 的来源。)

if (params.keys - allowed_params).empty?

params.keys是数组,allowed_params是数组。为什么减法未通过 .empty 测试?

要将其设置为重复:

$gem install bitfinex-rb pry

Ruby 来源

#!/opt/local/bin/ruby

# Annoying!
# Stuff is installed to $GEMPATH/bitfinex-rb-0.0.11
# But you have to invoke it as below.
require 'pry'
require 'bitfinex'

Bitfinex::Client.configure do |conf|
  conf.secret = ENV["BFX_API_SECRET"]
  conf.api_key = ENV["BFX_API_KEY"]
end

client = Bitfinex::Client.new

history_req = {
      'since' => 1444277602,
      'until' => 0,
      'limit' => 500,
      'wallet' => "exchange"
}

puts
print history_req.keys
puts
puts history_req.keys

client.history(
   currency = "USD",
   history_req
)

脚本输出(在 pry 的额外帮助下)

$ pry wtf.rb {"account"=>{"read"=>true, "write"=>false}, "history"=>{"read"=>true, "write"=>false}, "orders"=>{"read"=>true, "write"=>true}, "positions"=>{"read"=>true, "write"=>false}, "funding"=>{"read"=>true, "write"=>true}, "wallets"=>{"read"=>true, "write"=>false}, "withdraw"=>{"read"=>false, "write"=>false}}

["since", "until", "limit", "wallet"] since until limit wallet

Exception: Bitfinex::ParamsError: Bitfinex::ParamsError -- From: /opt/local/lib/ruby2.4/gems/2.4.0/gems/bitfinex-rb-0.0.11/lib/bitfinex/connection.rb @ line 23 @ level: 0 of backtrace (of 22).

18:     # Make sure parameters are allowed for the HTTP call
19:     def check_params(params, allowed_params)
20:       if (params.keys - allowed_params).empty?
21:         return params
22:       else
23:         raise Bitfinex::ParamsError
24:       end
25:     end
26: 
27:     def rest_connection
28:       @conn ||= new_rest_connection ...exception encountered, going interactive! [71] pry(main)>

github 上 Bitfinex gem 的来源:

https://github.com/bitfinexcom/bitfinex-api-rb

让我们来看看 docs for the history method:

Parameters:

  • currency (string) (defaults to: "usd") — (optional) Specify the currency, default “USD”
  • params (defaults to: {}) — :since [time] (optional) Return only the history after this timestamp.
  • params (defaults to: {}) — :until [time] (optional) Return only the history before this timestamp.
  • params (defaults to: {}) — :limit [int] (optional) Limit the number of entries to return. Default is 500.
  • params (defaults to: {}) — :wallet [string] (optional) Return only entries that took place in this wallet. Accepted inputs are: “trading”, “exchange”, “deposit”

因此 params 中允许的键是 :since:until:limit:wallet

您的 params 中的键是 'since''until''limit''wallet'

allowed_params = [:since, :until, :limit, :wallet]
params = {
  'since' => 1444277602,
  'until' => 0,
  'limit' => 500,
  'wallet' => "exchange"
}

params.keys - allowed_params
# => [:since, :until, :limit, :wallet]

(params.keys - allowed_params).empty?
# => false

解决方案是更改 history_req 的定义以使用符号键而不是字符串。

history_req = {
  since: 1444277602,
  until: 0,
  limit: 500,
  wallet: "exchange"
}

您可以在 the history method's source 中查看 allowed_params 的来源:

def history(currency="usd", params = {})
  check_params(params, %i{since until limit wallet})
  # ...
end

构造 %i{...}(注意 iproduces an array of Symbols,因此 [:since, :until, :limit, :wallet]