2012-05-02 4 views
1

Je me demandais si quelqu'un pouvait m'aider à comprendre le code Ruby ci-dessous? Je suis assez nouveau dans la programmation de Ruby et j'ai de la difficulté à comprendre la signification de chaque fonction.comprendre le code Ruby?

Lorsque j'utilise ceci avec mon nom d'utilisateur et mon mot de passe twitter comme paramètre, je reçois un flux d'échantillons de flux Twitter. Que dois-je faire avec ce code pour afficher uniquement les hashtags? J'essaie de rassembler les hashtags toutes les 30 secondes, puis de trier du moins à la plupart des occurrences des hashtags.

Ne cherchez pas de solutions, mais des idées. Merci!

require 'eventmachine' 
require 'em-http' 
require 'json' 

usage = "#{$0} <user> <password>" 
abort usage unless user = ARGV.shift 
abort usage unless password = ARGV.shift 

url = 'https://stream.twitter.com/1/statuses/sample.json' 

def handle_tweet(tweet) 
    return unless tweet['text'] 
    puts "#{tweet['user']['screen_name']}: #{tweet['text']}" 
end 

EventMachine.run do 
    http = EventMachine::HttpRequest.new(url).get :head => { 'Authorization' => [ user, password ] } 

    buffer = "" 

    http.stream do |chunk| 
    buffer += chunk 
    while line = buffer.slice!(/.+\r?\n/) 
     handle_tweet JSON.parse(line) 
    end 
    end 
end 
+2

Est-ce que cette question concerne Ruby, ou est-ce l'API de Twitter? Ne trouvez-vous pas comment obtenir les balises de hachage de l'API, ou ne comprenez-vous pas le code Ruby qui appelle l'API? – jefflunt

+0

c'est les deux. J'ai besoin de comprendre comment le code Ruby fonctionne en premier, afin de comprendre comment modifier le code pour obtenir les hashtags. – fokusfocus

Répondre

1
puts "#{tweet['user']['screen_name']}: #{tweet['text']}" 

Cette ligne vous montre un nom d'utilisateur suivi du contenu du tweet.

Prenons un peu de recul pendant une seconde.

Les étiquettes de hachage apparaissent à l'intérieur du contenu du tweet - cela signifie qu'elles sont dans le tweet ['texte']. Une balise de hachage prend toujours la forme d'un # suivi d'un tas de caractères non-espace. C'est vraiment facile à saisir avec une regex. API principale de Ruby facilite cela via String#scan. Exemple:

"twitter is short #foo yawn #bar".scan(/\#\w+/) # => ["#foo", "#bar"] 

Qu'est-ce que vous voulez est quelque chose comme ceci:.

def handle_tweet(tweet) 
    return unless tweet['text'] 
    # puts "#{tweet['user']['screen_name']}: #{tweet['text']}" # OLD 
    puts tweet['text'].scan(/\#\w+/).to_s 
end 

Tweet [ 'text'] scan (/ # \ w + /) est un tableau de chaînes. Vous pouvez faire ce que vous voulez avec ce tableau. Supposons que vous êtes nouveau à Ruby et que vous voulez imprimer les balises de hachage à la console, voici une brève note sur les tableaux d'impression avec puts:

puts array  # => "#foo\n#bar" 
puts array.to_s # => '["#foo", "#bar"]' 
+0

merci! Je commence à comprendre maintenant ... J'ai encore quelques questions: alors tweet est un paramètre de handle_tweet. mais comment tweet ['user'] ['screen_name'] renvoie le nom d'utilisateur et tweet ['text'] retourne le contenu du tweet? aussi, d'où vient le .to_s? – fokusfocus

+0

ok une autre question ... chaque fois que j'essaie d'exécuter ce code, il continue à imprimer le flux twitter sans fin ... ce qui est un bon moyen de casser la boucle et de quitter l'invite de commande? J'utilise le terminal dans mac – fokusfocus

+0

À droite, tweet est un paramètre de handle_tweet. tweet ['user'] implique que le type de tweet est un Hash ou un Set. Vous pouvez utiliser "puts tweet.class" dans votre fonction pour identifier la classe du tweet. Ainsi, le code appelle tweet ['user'] ['screen_name'], ce qui implique que tweet ['user'] est probablement aussi un hachage, et que les deux sont imbriqués comme des poupées Matryoshka. –

0
#Load Libraries 
require 'eventmachine' 
require 'em-http' 
require 'json' 


# Looks like this section assumes you're calling this from commandline. 
usage = "#{$0} <user> <password>" # $0 returns the name of the program 
abort usage unless user = ARGV.shift # Return first argument passed when program called 
abort usage unless password = ARGV.shift 

# The URL 
url = 'https://stream.twitter.com/1/statuses/sample.json' 

# method which, when called later, prints out the tweets 
def handle_tweet(tweet) 
    return unless tweet['text'] # Ensures tweet object has 'text' property 
    puts "#{tweet['user']['screen_name']}: #{tweet['text']}" # write the result 
end 

# Create an HTTP request obj to URL above with user authorization 
EventMachine.run do 
    http = EventMachine::HttpRequest.new(url).get :head => { 'Authorization' => [ user, password ] } 

    # Initiate an empty string for the buffer 
    buffer = "" 

    # Read the stream by line 
    http.stream do |chunk| 
    buffer += chunk 
    while line = buffer.slice!(/.+\r?\n/) # cut each line at newline 
     handle_tweet JSON.parse(line) # send each tweet object to handle_tweet method 
    end 
    end 
end 

Voici une version commentée de ce que la source est en train de faire. Si vous voulez juste le hashtag, vous voudrez réécrire handle_tweet à quelque chose comme ceci:

handle_tweet(tweet) 
    tweet.scan(/#\w/) do |tag| 
    puts tag 
    end 
end 
+0

merci! Je ne comprends toujours pas ce code si # Lire le flux par la ligne http.stream do | chunk | tampon + = morceau en ligne = buffer.slice! (/.+ \ r? \ N /) # couper chaque ligne à newline handle_tweet JSON.parse (ligne) # envoyer chaque objet tweet méthode handle_tweet final que signifie JSON.parse (ligne)? – fokusfocus

+0

L'URL en haut est un service Web RESTful. Lorsque vous envoyez votre requête HTTP à l'aide d'EventMachine, les services Web répondent avec du texte sous la forme JSON (JavaScript Object Notation). 'JSON.parse' prend le texte au format JSON et le convertit en objets ruby, c'est pourquoi vous pouvez avoir un objet' tweet' avec les propriétés 'text' et' user'. Essentiellement, il s'agit juste de convertir des objets JS en objets Ruby afin que vous puissiez travailler avec eux au lieu d'avoir à analyser le texte vous-même. – andrewheins