我在尝试设置这些实例变量时做错了什么?
What am i doing wrong in trying to set these instance variables?
当我调用 Quote#scrape_quote
时尝试在我的 Quote
实例中设置和/或访问这些变量时,我似乎遇到了一些基本错误。我可以看到这些值被抓取并保存到 scraped_values 哈希就好了,我只是无法访问变量,例如当我调用 quote.lives
时我得到 nil
.
我哪里错了?
quote.rb
class Quote < ApplicationRecord
require 'watir'
attr_accessor :lives, :benefit, :payment
def scrape_quote
rows = @browser.trs
quote_rows = rows[1..8]
scraped_values = {}
quote_rows.each do |row|
scraped_values[row.tds[0].text] = row.tds[1].text
end
@lives = scraped_values[0]
@benefit = scraped_values[1]
@payment = scraped_values[2]
puts scraped_values
end
end
scraped_values 是散列而不是数组。您正在尝试像访问数组一样访问它。
使用 row.tds[0].text
中的任何内容来引用哈希:
h = {a:1,b:2}
h[:a]
=> 1
一般情况
如果您只想将散列的值按顺序分配给成员变量,您可以使用 hash#values
return 值的并行分配,如下所示:
2.4.1 :001 > h = {}
=> {}
2.4.1 :002 > h[:one] = 1
=> 1
2.4.1 :003 > h[:two] = 2
=> 2
2.4.1 :004 > h[:three] = 3
=> 3
2.4.1 :005 > @one, @two, @three = h.values
=> [1, 2, 3]
2.4.1 :006 > @one
=> 1
2.4.1 :007 > @two
=> 2
2.4.1 :008 > @three
=> 3
2.4.1 :009 >
具体应用
您的具体代码将变为:
class Quote < ApplicationRecord
require 'watir'
attr_accessor :lives, :benefit, :payment
def scrape_quote
rows = @browser.trs
quote_rows = rows[1..8]
scraped_values = {}
quote_rows.each do |row|
scraped_values[row.tds[0].text] = row.tds[1].text
end
@lives, @benefit, @payment = scraped_values.values
puts scraped_values
end
end
构建哈希的惯用方法是使用 map
而不是 each
并且 不要使用 局部变量的预先声明。
scraped_values = quote_rows.map do |row|
[row.tds[0].text, row.tds[1].text]
end.to_h
而不是 scraped_values[0]
你需要这样的东西:scraped_values[scraped_values.keys[0]]
,因为 scraped_values 不是数组并且 0, 1, 2 就像任何其他丢失的键一样,所以散列 returns nil
.
当我调用 Quote#scrape_quote
时尝试在我的 Quote
实例中设置和/或访问这些变量时,我似乎遇到了一些基本错误。我可以看到这些值被抓取并保存到 scraped_values 哈希就好了,我只是无法访问变量,例如当我调用 quote.lives
时我得到 nil
.
我哪里错了?
quote.rb
class Quote < ApplicationRecord
require 'watir'
attr_accessor :lives, :benefit, :payment
def scrape_quote
rows = @browser.trs
quote_rows = rows[1..8]
scraped_values = {}
quote_rows.each do |row|
scraped_values[row.tds[0].text] = row.tds[1].text
end
@lives = scraped_values[0]
@benefit = scraped_values[1]
@payment = scraped_values[2]
puts scraped_values
end
end
scraped_values 是散列而不是数组。您正在尝试像访问数组一样访问它。
使用 row.tds[0].text
中的任何内容来引用哈希:
h = {a:1,b:2}
h[:a]
=> 1
一般情况
如果您只想将散列的值按顺序分配给成员变量,您可以使用 hash#values
return 值的并行分配,如下所示:
2.4.1 :001 > h = {}
=> {}
2.4.1 :002 > h[:one] = 1
=> 1
2.4.1 :003 > h[:two] = 2
=> 2
2.4.1 :004 > h[:three] = 3
=> 3
2.4.1 :005 > @one, @two, @three = h.values
=> [1, 2, 3]
2.4.1 :006 > @one
=> 1
2.4.1 :007 > @two
=> 2
2.4.1 :008 > @three
=> 3
2.4.1 :009 >
具体应用
您的具体代码将变为:
class Quote < ApplicationRecord
require 'watir'
attr_accessor :lives, :benefit, :payment
def scrape_quote
rows = @browser.trs
quote_rows = rows[1..8]
scraped_values = {}
quote_rows.each do |row|
scraped_values[row.tds[0].text] = row.tds[1].text
end
@lives, @benefit, @payment = scraped_values.values
puts scraped_values
end
end
构建哈希的惯用方法是使用 map
而不是 each
并且 不要使用 局部变量的预先声明。
scraped_values = quote_rows.map do |row|
[row.tds[0].text, row.tds[1].text]
end.to_h
而不是 scraped_values[0]
你需要这样的东西:scraped_values[scraped_values.keys[0]]
,因为 scraped_values 不是数组并且 0, 1, 2 就像任何其他丢失的键一样,所以散列 returns nil
.