【问题标题】:understanding Ruby code?了解 Ruby 代码?
【发布时间】:2012-05-11 12:03:07
【问题描述】:

我想知道是否有人可以帮助我理解下面的 Ruby 代码?我对 Ruby 编程很陌生,无法理解每个函数的含义。

当我使用我的 twitter 用户名和密码作为参数运行它时,我会得到一个 twitter 提要样本流。我需要对这段代码做什么才能只显示主题标签?

我尝试每 30 秒收集一次主题标签,然后从出现的主题标签最少到最多进行排序。

不是在寻找解决方案,而是在寻找想法。谢谢!

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

【问题讨论】:

  • 这个问题是关于 Ruby 的,还是关于 Twitter API 的?您不知道如何从 API 中获取哈希标签,或者您不了解调用 API 的 Ruby 代码吗?
  • 两者兼而有之。我需要先了解 Ruby 代码的工作原理,以便弄清楚如何修改代码以获取主题标签。

标签: ruby twitter hashtag


【解决方案1】:
puts "#{tweet['user']['screen_name']}: #{tweet['text']}"

该行显示的是用户名,后跟推文的内容。

让我们退后一步。

哈希标签出现在推文的内容中——这意味着它们在推文['text'] 中。哈希标记始终采用 # 后跟一堆非空格字符的形式。使用正则表达式真的很容易掌握。 Ruby 的核心 API 通过String#scan 促进了这一点。示例:

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

你想要的是这样的:

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+/) 是一个字符串数组。你可以用这个数组做任何你想做的事情。假设您是 Ruby 新手,想将哈希标签打印到控制台,这里有一个关于使用 puts 打印数组的简要说明:

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

【讨论】:

  • 谢谢!我现在开始明白了……不过我还有一些问题:所以tweet 是handle_tweet 的一个参数。但是 tweet['user']['screen_name'] 如何返回用户名,而 tweet['text'] 如何返回推文内容呢?还有,.to_s 是从哪里来的?
  • 确定另一个问题...每当我尝试运行此代码时,它会不断打印 twitter 流...什么是打破循环并退出到命令提示符的好方法?我在 mac 中使用终端
  • 对,tweet是handle_tweet的一个参数。 tweet['user'] 暗示 tweet 的类型是 Hash 或 Set。您可以在函数中使用“puts tweet.class”来识别推文的类。因此,代码调用了 tweet['user']['screen_name'],这意味着 tweet['user'] 可能也是一个哈希,并且两者像套娃一样嵌套。
  • 无法帮助您处理 Mac 问题。如果您只想打印几个并退出,您可以使用计数器并跟踪您打印了多少次,然后中断/返回。您可能会发现 ruby.learncodethehardway.org/book/ex33.htmlruby.learncodethehardway.org/book/ex32.html 有助于理解 Ruby 中的循环。
【解决方案2】:
#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

这是来源正在做什么的注释版本。如果您只想要主题标签,则需要将 handle_tweet 重写为:

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

【讨论】:

  • 谢谢!我仍然不明白这段代码 # 逐行读取流 http.stream do |chunk| buffer += chunk while line = buffer.slice!(/.+\r?\n/) # 在换行处剪切每一行 handle_tweet JSON.parse(line) # 将每个推文对象发送到 handle_tweet 方法 end JSON.parse(行)是什么意思?
  • 顶部的 URL 是一个 RESTful Web 服务。当您使用 EventMachine 发送 HTTP 请求时,Web 服务会以 JSON(JavaScript 对象表示法)形式的文本进行响应。 JSON.parse 获取 JSON 格式的文本并将其转换为 ruby​​ 对象,这就是为什么您可以拥有具有 textuser 属性的 tweet 对象。本质上,它只是将 JS 对象转换为 Ruby 对象,这样您就可以使用它们,而不必自己解析文本。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 2015-11-07
  • 2010-09-14
  • 2013-06-04
  • 1970-01-01
  • 2018-07-02
  • 2015-12-18
  • 1970-01-01
相关资源
最近更新 更多