模块中的机械化,名称错误“代理”
Mechanize in Module, Nameerror ' agent'
寻求有关如何修复此错误并重构此代码以改进它的建议。
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'
Ruby 有一个命名约定。 agent
是 class 范围内的 局部变量 。要使其对其他方法可见,您应该通过将其命名为 @@agent
使其成为 class 变量 ,并且它将在 [= 的所有对象之间共享15=]。不过,首选方法是将其命名为 @agent
,使其成为 实例变量 。 WebBot
的每个对象都会有自己的 @agent
。但是你应该把它放在 initialize
中,当你使用 new
创建一个新对象时, initialize
将被调用
class WebBot
def initialize
@agent = Mechanize.new do |a|
a.user_agent_alias = 'Windows Chrome'
end
end
.....
page
也会出现同样的错误。您在 form
中将其定义为 局部变量 。当 form
完成执行时,它将被删除。你应该使它成为一个实例变量。幸运的是,您不必将它放在 initialize
中。您可以在 form
中定义它。对象在调用 form
后将拥有自己的 @page
。在 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|
.....
这些更改将解决名称错误。顺便说一句,重构是另一个故事。
寻求有关如何修复此错误并重构此代码以改进它的建议。
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'
Ruby 有一个命名约定。 agent
是 class 范围内的 局部变量 。要使其对其他方法可见,您应该通过将其命名为 @@agent
使其成为 class 变量 ,并且它将在 [= 的所有对象之间共享15=]。不过,首选方法是将其命名为 @agent
,使其成为 实例变量 。 WebBot
的每个对象都会有自己的 @agent
。但是你应该把它放在 initialize
中,当你使用 new
initialize
将被调用
class WebBot
def initialize
@agent = Mechanize.new do |a|
a.user_agent_alias = 'Windows Chrome'
end
end
.....
page
也会出现同样的错误。您在 form
中将其定义为 局部变量 。当 form
完成执行时,它将被删除。你应该使它成为一个实例变量。幸运的是,您不必将它放在 initialize
中。您可以在 form
中定义它。对象在调用 form
后将拥有自己的 @page
。在 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|
.....
这些更改将解决名称错误。顺便说一句,重构是另一个故事。