2013-08-21 2 views
0

У меня следующий код создает класс Parser, который имеет множество методов parse_something. Затем, наконец, они объединяются в методе parse:Как использовать Class_name.method вместо Class_name.new.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 

(и т.д ...)

Так прямо сейчас, я использую это так:

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

Parser.new.parse html_pet_supplies 

Но я хотел бы чтобы использовать его как это вместо: Parser.parse html_pet_supplies

Я попытался удалить new но я получил эту ошибку:

NoMethodError: undefined method `parse' for Parser:Class

Что такое самый простой способ изменения кода, так что я просто делаю Parser.parse?

ответ

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).

+0

Я добавил 'self.' перед всеми другими методами и работал. Это тоже вариант, не так ли? – alexchenco

+0

Конечно, хотя писать тесты, например, обычно проще (вы пишете тесты, не так ли?). – Stefan

+0

Да, я ничего не менял в тестах. Они все равно прошли. – alexchenco

1

Используйте статический метод декларации

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

Вы можете затем вызвать его Parser.parse filename

Update Вы имеете переменная экземпляра объявлена ​​в вашей разборе логики @data, так что вы не можете заставить его работать с текущей логикой. Вам нужно будет создать экземпляр, чтобы иметь возможность вызвать parse_department.

** Дальнейшее обновление **

Короткий ответ Ваша текущая логика просто отлично.

Длинный ответ Это больше о ООП. В методе parser # parse у вас есть @data объявление переменной экземпляра. @data может существовать только для объекта, а не для класса, что, в свою очередь, означает, что вы можете использовать его только в методе экземпляра, а не в статическом методе. Когда вы вызываете Parser.new, он создает объект, и именно тогда может существовать @data. Хотя статические методы могут быть вызваны в классе непосредственно без создания объекта. Подробнее Understanding Ruby class vs instance methods

+0

Странно, я изменил его на 'self.parse', но теперь как' 'Parser.parse' и Parser.new.parse' перестал работать:' Сбой/Ошибка: пусть (: department_hash) {Parser.parse html_pet_supplies} NoMethodError : undefined method 'parse_department 'для Parser: Class # ./parser.rb:9:in' parse'' – alexchenco

+0

Это потому, что вы сделали только один метод статическим, а не другим. Если у вас есть методы, специфичные для объекта, то вы не можете объявлять статические методы для выполнения вашей работы. Вам нужно будет жить с созданием новых экземпляров. Это больше о ООП, поэтому я бы предложил вам прочитать о статических методах и объектных методах, чтобы получить понимание и знать, что это сработает для вас. – ch4nd4n

+0

Извините, я не очень хорошо знаком с созданием классов и статических методов, не могли бы вы привести мне пример? 'Вам нужно было бы создать экземпляр, чтобы иметь возможность вызвать parse_department.' – alexchenco

Смежные вопросы