【问题标题】:Why is this ruby string casting to_i as 200?为什么这个红宝石字符串将 to_i 转换为 200?
【发布时间】:2013-11-15 08:58:44
【问题描述】:

我正在开发一个通过 RestClient 连接到后端数据存储(也是 ruby​​,而不是 rails)的 rails 应用程序。我刚刚将此方法添加到 rails 应用程序的后端 api 类,以从后端获取文件大小:

class Backend < ActiveResource::Base
  def self.file_size(file_key)
    RestClient.get("#{SERVER_URL}/files/#{file_key}/size")
  end
end

而后端对应的代码是:

get '/files/:file_id/size' do
  json_for file.size
end

对于一个示例文件,Backend.file_size(file.key) 返回“198942”,但是当这个属性被保存到数据库时(在一个整数字段中),它被转换为 int 为 200。

我在 Rails 控制台中玩过这个,结果令人困惑。

test_size = Backend.file_size(file.key)
=> "198942"
control_size = "198942"
=> "198942"

test_size.class
=> String
control_size.class
=> String

test_size.bytes.to_a
=> [49, 57, 56, 57, 52, 50]
control_size.bytes.to_a
=> [49, 57, 56, 57, 52, 50]

test_size.to_i
=> 200
control_size.to_i
=> 198942

Integer(test_size)
=> 198942
Integer(control_size)
=> 198942

test_size.to_s.to_i
=> 200
control_size.to_s.to_i
=> 198942

test_size.tr('^A-Za-z0-9', '').to_i
=> 198942

我还检查了编码,其余响应是 US-ASCII,但是当 force_encoded 为 UTF-8 时,它的行为是相同的。奇怪的是,test_size 在 Integer 和 tr sub 下正确转换以删除任何非打印字符,但字节内容与控制字符串相同。

我最终找到了这个问题的根源(在下面回答),但如果有人以前有过这种经验,并且如果有人深入了解为什么 RestClient 会以这种方式响应(在这种特殊情况下),我会很感兴趣。

【问题讨论】:

    标签: ruby-on-rails ruby rest rest-client


    【解决方案1】:

    经过更多调查(查看 test_size 和 control_size 的公共方法),我发现来自 RestClient 的返回值是一个 RestClient::Response,尽管它看起来像 String 一样。

    test_size.is_a?(String)
    => true
    test_size.is_a?(RestClient::Response)
    => true
    
    test_size.code
    => 200
    

    这让我觉得这是一个非常意外的行为(尽管我知道通过 rest 客户端而不是 JSON 发送裸值有点不寻常),如果有人知道 RestClient::Response 对象如何/为什么看起来如此,我会很好奇是一个奇怪的混合对象,表现为一个字符串,并且似乎已经猴子修补了一堆字符串方法(但不是全部 - 例如tr)。

    我只是通过重构前端和后端 API 类来传递 JSON 对象解决了这个问题。

    前端重构代码:

    class Backend < ActiveResource::Base
      def self.file_size(file_key)
        JSON.parse(RestClient.get("#{SERVER_URL}/files/#{file_key}/size"))
      end
    end
    

    后端代码:

    get '/files/:file_id/size' do
      json_for file.size
    end
    
    class File
      def size
        {
          size: size
        }
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多