Reputation: 55263
I have the following code creates a Parser
class which has many parse_something
methods. Then finally they are merged in the parse
method:
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...)
So right now, I'm using it like this:
def html_pet_supplies
File.open("amazon_pet_supplies.html")
end
Parser.new.parse html_pet_supplies
But I would like to use it like this instead: Parser.parse html_pet_supplies
I tried removing new
but I got this error:
NoMethodError: undefined method `parse' for Parser:Class
What's the simplest way of changing the code so that I just do Parser.parse
?
Upvotes: 0
Views: 109
Reputation: 114138
Instead of rewriting all your methods to class methods, you could create a Parser
instance and call Parser#parse
from Parser.parse
:
class Parser
def self.parse(html)
self.class.new.parse(html)
end
def parse(html)
@data = Nokogiri.HTML(open(html))
# ...
end
#...
end
Now Parser.parse(html)
is equivalent to Parser.new.parse(html)
.
Upvotes: 1
Reputation: 4197
Use static method declaration
class Parser
def self.parse(html)
#Parsing logic
end
end
You could then invoke it by Parser.parse filename
Update You have instance variable declared in your parsing logic @data
so you cannot get it working with current logic. You would have to create instance to be able to call parse_department.
** Further Update **
Short answer Your current logic is just fine.
Long answer It's more about OOP. In Parser#parse method you have @data
instance variable declaration. @data
can exist only for an object not for class, which in turn means that you can have it only in an instance method and not in static method. When you call Parser.new
it create an object and that is when @data
can exist. While static methods can be invoked on a class directly without creating an object. Read more Understanding Ruby class vs instance methods
Upvotes: 1