Ruby:方法不会在定义的文件外部运行 - “无法将符号转换为整数(TypeError)”

时间:2012-07-01 19:13:13

标签: ruby mongodb

我是一个红宝石新手,这是我的第一个(现在的命令行)计划。 首先,一些来源。

file:AccessDb.rb

require 'mongo'
require 'json'
(...)

class AccessDb
  def initialize dbname, collection #, username, password
    @dbname = dbname
    @collection = collection
    @conn = Mongo::Connection.new
    @db   = @conn[dbname]
    @coll = @db[collection]
  end

  def upsert_by_meta json
    # print json
    @coll.update({ :hash_md5 => json[:hash_md5] }, json, :upsert => true)
  end
end

使用

file:Downloader.rb

require 'curb'
require 'yaml'
require 'json'
(...)

class Downloader
  def initialize(directory)
    @PASS=nil
    @COOKIE=nil
    @filename=nil
    @full_file_location = nil
    @target_dir = directory
    File.exists? @target_dir # File.directory? @target_dir
    @c = Curl::Easy.new
    curl_setup
    @mongo = AccessDb.new "meta","meta"
  end

  def parse_link_info(url)
    json = {}

    json[:link_requested] = url
    if @c.last_effective_url != url
      then json[:link_final] = @c.last_effective_url end

    json[:link_filename_requested] =  @filename
    @final_filename = @c.last_effective_url.split(/\?/).first.split(/\//).last
    if @final_filename != @filename
      then json[:link_filename_delivered] = @final_filename end

    json[:link_filetime] = Time.at(@c.file_time).utc.to_s

    json[:content_lenght] = @c.downloaded_content_length
    json[:content_type] = @c.content_type

    @hash = MovieHasher::compute_hash(@save_location)
    @hash = MovieHasher::compute_hash(@save_location)

    if !@hash.nil?
      then json[:hash_bigfile] = @hash end

    json[:hash_md5] = Digest::MD5.hexdigest(File.read(@save_location))

    JSON.pretty_generate(json)
  end

(json是一些生成的json文件)

在AccessDb.rb测试中使用Downloader.rb中的代码可以很好地工作,但是当在Downloader.rb中使用该方法时,我得到以下输出:

 D:/Dropbox/#code/PracaInz-Program/AccessDb.rb:20:in `[]': can't convert Symbol into Integer (TypeError)
from D:/Dropbox/#code/PracaInz-Program/AccessDb.rb:20:in `upsert_by_meta'
from D:/Dropbox/#code/PracaInz-Program/Downloader.rbw:158:in `block in add_links'
from D:/Dropbox/#code/PracaInz-Program/Downloader.rbw:148:in `each'
from D:/Dropbox/#code/PracaInz-Program/Downloader.rbw:148:in `add_links'
from D:/Dropbox/#code/PracaInz-Program/Downloader.rbw:189:in `<main>'
[Finished in 4.9s with exit code 1]

在一个完全在一个文件中测试的方法代码中。如何编写它以便它可以使用符号但在特定文件之外工作。 THX

def parse_link_info(url)
  json = {}

  json[:link_requested] = url
  if @c.last_effective_url != url
    then json[:link_final] = @c.last_effective_url end

  json[:link_filename_requested] =  @filename
  @final_filename = @c.last_effective_url.split(/\?/).first.split(/\//).last
  if @final_filename != @filename
    then json[:link_filename_delivered] = @final_filename end

  json[:link_filetime] = Time.at(@c.file_time).utc.to_s

  json[:content_lenght] = @c.downloaded_content_length
  json[:content_type] = @c.content_type

  @hash = MovieHasher::compute_hash(@save_location)
  @hash = MovieHasher::compute_hash(@save_location)

  if !@hash.nil?
    then json[:hash_bigfile] = @hash end

  json[:hash_md5] = Digest::MD5.hexdigest(File.read(@save_location))

  JSON.pretty_generate(json)
end

def add_links(url_array,cred=nil,ref=nil,cookie=nil)
  link_setup(cred,ref,cookie)
  url_array.each do |single_url|
    @c.url=single_url
    @filename = single_url.split(/\?/).first.split(/\//).last
    @save_location = @target_dir + '\\' + @filename
    # puts @save_location
    @c.perform
    File.open(@save_location,"wb").write @c.body_str

    json = parse_link_info single_url
    # puts json
    id = @mongo.upsert_by_meta json
    puts id
    json["_id"] = id
    File.open(@save_location + :"meta.json","w").write json
  end
end

编辑:更多代码(json定义),完整跟踪

1 个答案:

答案 0 :(得分:0)

parse_link_info返回JSON.pretty_generate(json),即一个字符串。

您将其结果传递给upsert_by_meta作为其json参数,该参数尝试将其作为哈希(您执行json[:hash_md5])访问,而您不能使用字符串。 String的[]方法要求你传递一个整数(或一对整数),因此关于无法将符号转换为整数的方法

如果parse_link_info刚刚返回你的json对象而不是调用JSON.pretty_generate

,看起来你显示的代码会起作用