0

私は Ruby の初心者で、これが私の最初の (今のところコマンドライン) プログラムです。まず、いくつかのソース。

ファイル: 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

使用して

ファイル: 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]

1つのファイル内でテストされた完全に機能するメソッドコードで..シンボルを使用できるが、その特定のファイルの外部で機能するように記述するにはどうすればよいですか。どうも

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 定義)、完全なトレース

4

1 に答える 1

0

parse_link_infoを返しますJSON.pretty_generate(json)。つまり、文字列です。

その結果を json パラメーターとして渡します。upsert_by_metaこれは、文字列では実行できないハッシュとしてアクセスしようとします (そうしますjson[:hash_md5])。String の [] メソッドは、整数 (または整数のペア) を渡すことを期待しているため、シンボルを整数に変換できないことに関するメソッド

parse_link_info が JSON.pretty_generate を呼び出すのではなく、json オブジェクトを返しただけの場合、表示したコードが機能するように見えます

于 2012-07-02T19:59:02.077 に答える