-1

我正在使用以下代码来废弃网站中的部分:

class Parser
  def self.parse(html)
    @data = Nokogiri.HTML(open(html))
    merged_hashes = {}

    array_of_hashes = [
      parse_department,
      parse_super_saver,
      parse_new_arrivals,
      parse_out_of_stock,
      parse_categories,
      parse_results,
      parse_category
    ]
    array_of_hashes.inject(merged_hashes,:update)

    return merged_hashes
  end

  .
  .
  .

  def self.parse_results
    results = @data.css('#refinements ul').first
    unless results
      @results_hash = {}
      return @results_hash
    end

    if results.css('li:nth-child(1) a span').text == "Pet Supplies"
      @results_hash = {}
      @results_hash[:results] ||= {}
      @results_hash[:results] = @data.at_css('#resultCount span').text[/(\S+) Results$/i, 1].delete(",").to_i
    else
      @results_hash = {}
    end

    return @results_hash
  end

正如您在这部分中看到的:

    results = @data.css('#refinements ul').first
    unless results
      @results_hash = {}
      return @results_hash
    end

results如果是,我将停止代码nil。原因是如果将.at_css下面的方法应用于 nil 值,代码将中断。

发生这种情况是因为有时 html 没有该方法正在寻找的 CSS 选择器。

这就是为什么我想在那里停止代码。

我必须在每种方法中重复这一点。有没有更简单或更优雅的方式来做到这一点?

4

1 回答 1

3

你可以写

return {} if results.nil?

不过,我确实有一些建议:

  • 你真的需要设置@results_hash吗?因为我认为它根本不应该是一个实例变量。def self.parse_results无论如何,您都在使用类方法 ( )。

  • 为什么需要将结果嵌套在 中@results_hash[:results]?在我看来,直接填写就足够了results_hash。这样,您可以使用空哈希初始化results_hash变量一次。

  • 该行@results_hash[:results] ||= {}确实是多余的,因为无论如何您都会立即在下一行覆盖该值。

  • Ruby 隐式返回最后一个表达式的值,因此您可以删除最后一个return。尽管人们需要习惯这种表示法,但它的使用范围很广,通常被认为是“好风格”</p>

也就是说,我会这样写方法:

def self.parse_results
  results_hash = {}

  results = @data.css('#refinements ul').first
  return results_hash if results.nil?

  if results.css('li:nth-child(1) a span').text == "Pet Supplies"
    results_hash = @data.at_css('#resultCount span')
                        .text[/(\S+) Results$/i, 1]
                        .delete(",")
                        .to_i
  end

  results_hash
end
于 2013-08-23T06:54:42.853 回答