2010-08-28 5 views
0
 

require 'net/http'; 
require 'uri'; 
require 'rexml/document'; 
require 'sqlite3'; 

def download_torrent(episode_id, torrent_url, limit = 10) 
    # Check to make sure we haven't been trapped in an infinite loop 
    if limit == 0 then 
    puts "Too much redirection, skipping #{episode_id}"; 
    return true; 
    else 
    # Convert the URL of the torrent into a URI usable by Net:HTTP 
    torrent_uri = URI.parse(torrent_url); 
    # Open a connection to the torrent URL 
    Net::HTTP.get_response(torrent_uri) { |http| 
     # Check to see if we were able to connect to the torrent URL 
     case http 
     # We connected just fine 
     when Net::HTTPSuccess then 
     # Create a torrent file to store the data in 
     File.open("#{episode_id}.torrent", 'wb') { |torrent_file| 
      # Write the torrent data to the torrent file 
      torrent_file.write(http.body); 
      # Close the torrent file 
      torrent_file.close 
      # Check to see if we've download a 'locked' torrent file (html) instead of a regular torrent (.torrent) 
      if(File.exists?('download.torrent.html')) 
      # Delete the html file 
      File.delete('download_torrent.html'); 
      return false; 
      else 
      return true; 
      end 
     } 
     when Net::HTTPRedirection then 
      download_torrent(episode_id, http['location'], limit - 1); 
     end 
    } 
    end 
end 
 

Ma fonction ne retourne pas 'true' au sens booléen. Il continue à renvoyer <Net::HTTPFound:0x3186c60>, ce qui entraîne la condition que ma fonction "Renvoie cette fonction true" conditionne l'évaluation à false. Pourquoi cette fonction ne sort pas quand elle frappe la première déclaration de retour (comme toutes les autres langues que j'ai utilisées)Obtention d'une valeur de retour parmi plusieurs blocs avec Ruby

Je sais que c'est totalement une question Ruby Newbie (I Rhymed!), Mais j'apprécie l'aide.

Répondre

1

Apparemment, Net::HTTP.get_response a passé Net::HTTPFound instance comme http paramètre dans le bloc interne. Par conséquent, l'instruction return n'a jamais été atteinte et votre méthode download_torrent a renvoyé le dernier objet "sur la pile", qui se trouve être la valeur de retour de Net::HTTP.get_response.

Si cette description est un peu vague, voici un exemple plus court. Avec la partie return true, la méthode do_it renverra true. Sans cela, la méthode do_it retournera l'objet retourné par do_that.

def do_it 
    do_that {|param| 
# return true; 
    } 
end 

J'ai peu d'expérience avec net/http package, vous aurez probablement lire docs et gérer la réponse Net::HTTPFound dans votre opérateur case en quelque sorte.

Personnellement, cela a toujours fonctionné pour moi dans l'extraction du contenu de la page Web: Net::HTTP.get(URI.parse(url)). C'est plus simple sans bloc de code et renvoie simplement le contenu sous forme de chaîne.

Questions connexes