1

Ищете советы по устранению этой ошибки и рефакторинг этого кода, чтобы улучшить его.Механизировать в модуле, агент «Имущество»

require 'mechanize' 
require 'pry' 
require 'pp' 




module Mymodule 
    class WebBot 

    agent = Mechanize.new { |agent| 
     agent.user_agent_alias = 'Windows Chrome' 
    } 

    def form(response) 
     require "addressable/uri" 
     require "addressable/template" 
     template = Addressable::Template.new("http://www.domain.com/{?query*}") 
     url = template.expand({"query" => response}).to_s 
     page = agent.get(url) 
    end 

    def get_products 
     products = [] 
     page.search("datatable").search('tr').each do |row| 
     begin 
      product = row.search('td')[1].text 
     rescue => e 
      p e.message 
     end 
     products << product 
     end 
     products 
    end 
    end 
end 

Вызов модуля:

response = {size: "SM", color: "BLUE"} 

t = Mymodule::WebBot.new 
t.form(response) 
t.get_products 

Ошибка:

NameError: undefined local variable or method `agent' 

ответ

2

Рубин имеет именование. agent - это локальная переменная в классе scope. Чтобы сделать его видимым для других методов, вы должны сделать его переменной , назвав ее @@agent, и она будет доступна для всех объектов WebBot. Предпочтительный способ состоит в том, чтобы сделать его переменной переменной, назвав ее @agent. Каждый объект WebBot будет иметь свой собственный @agent. Но вы должны положить его в initialize, initialize будет вызываться при создании нового объекта с new

class WebBot 
    def initialize 
    @agent = Mechanize.new do |a| 
     a.user_agent_alias = 'Windows Chrome' 
    end 
    end 
..... 

И та же ошибка будет происходить в page. Вы определили его в form как локальную переменную . Когда form закончит выполнение, он будет удален. Вы должны сделать это переменной экземпляра . К счастью, вам не нужно класть его в initialize. Вы можете определить его здесь в form. И объект будет иметь свой собственный @page после вызова form. Делайте это в form:

def form(response) 
    require "addressable/uri" 
    require "addressable/template" 
    template = Addressable::Template.new("http://www.domain.com/{?query*}") 
    url = template.expand({"query" => response}).to_s 
    @page = agent.get(url) 
end 

И не забудьте изменить каждое вхождение page и agent к @page и @agent. В вашем get_products, например:

def get_products 
    products = [] 
    @page.search("datatable").search('tr').each do |row| 
    ..... 

Эти изменения позволят устранить ошибки имени. Рефакторинг - это еще одна история.

+0

ошибки имен, хотя и не синтаксические ошибки. – pguardiario

+0

Да. Полностью верно. Я исправлю это. –

+0

Работает, отлично, спасибо. Любые советы по очистке кода? – user2012677

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