0

我有以下代码创建了一个Parser有很多parse_something方法的类。然后最后将它们合并到parse方法中:

class Parser
  def 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
    ]
    array_of_hashes.inject(merged_hashes,:update)

    return merged_hashes
  end

  def parse_department  
    department = @data.css('#ref_2619534011')

    @department_hash = {}
    department.css('li').drop(1).each do | department |
      department_title = department.css('.refinementLink').text
      department_count = department.css('.narrowValue').text[/[\d,]+/].delete(",").to_i
      @department_hash[:department] ||= {}
      @department_hash[:department]["Pet Supplies"] ||= {}
      @department_hash[:department]["Pet Supplies"][department_title] = department_count
    end 

    return @department_hash
  end 

  def parse_super_saver  

(ETC...)

所以现在,我像这样使用它:

def html_pet_supplies
  File.open("amazon_pet_supplies.html")
end

Parser.new.parse html_pet_supplies

但我想像这样使用它:Parser.parse html_pet_supplies

我尝试删除new,但出现此错误:

NoMethodError:解析器的未定义方法“解析”:类

更改代码以便我这样做的最简单方法是什么Parser.parse

4

2 回答 2

1

Parser您可以创建一个实例并Parser#parse从以下位置调用,而不是将所有方法重写为类方法Parser.parse

class Parser
  def self.parse(html)
    self.class.new.parse(html)
  end

  def parse(html)
    @data = Nokogiri.HTML(open(html))
    # ...
  end
  #...
end

现在Parser.parse(html)相当于Parser.new.parse(html).

于 2013-08-21T07:20:24.447 回答
1

使用静态方法声明

class Parser
  def self.parse(html)
    #Parsing logic
  end
end

然后你可以调用它Parser.parse filename

更新您在解析逻辑中声明了实例变量,@data因此您无法使其与当前逻辑一起使用。您必须创建实例才能调用 parse_department。

** 进一步更新 **

简短回答您当前的逻辑很好。

长答案更多的是关于OOP。在 Parser#parse 方法中,您有@data实例变量声明。@data只能为对象而不是类存在,这反过来意味着您只能在实例方法中而不是静态方法中拥有它。当您调用Parser.new它时,创建一个对象,即何时@data可以存在。虽然可以直接在类上调用静态方法而无需创建对象。阅读更多了解 Ruby 类与实例方法

于 2013-08-21T06:42:58.360 回答