我有一些代码将文件读入一个行数组,然后解析这些行以获取结构化数据。输入文件有各种不同的数据类型,需要以不同的方式处理,另外还有各种帐户(手机号码)的主要部分。
我循环查找帐户行,识别帐户,然后我想使用该帐户,直到我遇到下一个帐户行。两者之间的行可能代表属于该帐户的各种类型的数据。问题是,在找到帐户行并设置局部变量(cur_num)后,当我想使用它时,变量设置为nil。为什么,这是怎么回事?我正在学习Ruby,所以我想要的不仅仅是修复 - 我想了解它为什么会这样工作。
这是我的代码:
count = 0
cur_num = ""
lines.each do |line|
unless (line.strip.eql?("")) # edited due to comment from normalocity
if (line.slice(0,15) == "Mobile Number:,")
cur_num = line.slice(15,12)
count = 1
puts "Current Number: #{cur_num}"
#puts "Object Type: #{cur_num.class}"
else
data = line.strip.split(',')
if (data.length > 8)
data.unshift(cur_num)
#if (count.modulo(10) == 0 || count == 1)
puts "[#{cur_num}] #{data.inspect}"
#pp data
#end
count += 1
end
end
end
end
输入数据结构的概述如下所示:
Account 1
Data Section A
data line 1
data line 2
Data Section B
data line 1
data line 2
Account 2
Data Section A
data line 1
data line 2
Data Section B
data line 1
data line 2
end
将代码添加到重复行数组中,如果您尝试复制,则应将其粘贴到上面的代码示例中。我把它放在最后,试图让我的问题更具可读性:
lines = []
lines.push("ATT Wireless Bill")
lines.push("")
lines.push("Mobile Number:,770-555-1212")
lines.push("item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge")
lines.push("")
lines.push("1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00")
lines.push("")
lines.push("2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00")
lines.push("")
lines.push("1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00")
lines.push("")
lines.push("Mobile Number:,770-555-1213")
lines.push("item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge")
lines.push("")
lines.push("1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00")
lines.push("")
lines.push("2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00")
lines.push("")
lines.push("1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00")
lines.push("")
答案 0 :(得分:1)
回答答案Why / How is my variable getting set to nil
如果没有cur_num = ""
,则不会在循环外部初始化cur_num(lines.each
)。
因此,cur_num
在每个循环中初始化。
我希望会出现undefined local variable or method
错误,但是如果if-branch没有执行,那么在每个循环中似乎都会创建cur_num
。所以你有cur_num
,但没有值(或更好:它是零)。
我添加了一个简短的例子来表明,即使代码没有执行,也会创建一个变量:
if false
a = 1
else
p a #works fine, a was created, but it is nil
p b #undefined local variable or method `b'
end
附录二:
以下代码显示,循环内的变量是“循环内部”。第二个(和后续)循环在没有变量a的情况下开始。
#~ a = 0 # uncomment to compare
5.times{
if defined? a
puts "a is defined as #{a.inspect}"
else
puts "a is not defined"
a = 1 #define it now
end
}
我重新设计了你的代码。当我解析像你这样的文本时,我更喜欢使用带有正则表达式的case
- 语句:
count = 0
cur_num = ""
DATA.each_line do |line|
case line
when /\A\s\Z*/ #skip empty lines
when /Mobile Number:,(.{12})/
cur_num = $1
count = 1
puts "Current Number: #{cur_num}"
#puts "Object Type: #{cur_num.class}"
else
data = line.strip.split(',')
if data.length > 8
data.unshift(cur_num)
#if (count.modulo(10) == 0 || count == 1)
puts "[#{cur_num}] #{data.inspect}"
#pp data
#end
count += 1
end #(data.length > 8)
end #case line
end
__END__
ATT Wireless Bill
Mobile Number:,770-555-1212
item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge
1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00
2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00
1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00
Mobile Number:,770-555-1213
item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge
1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00
2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00
1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00
答案 1 :(得分:0)
在盯着这个超过一个小时之后,比较两个几乎相同的版本,一个有效,一个没有,我能够通过评论出一条线来使它失败或成功。 这是我正在运行的确切代码: [编辑注释,更改代码以防止代码示例中的垂直滚动条]
#!/usr/local/bin/ruby
my_input ="ATT Wireless Bill\n\nMobile Number:,770-555-1212\n\nitem,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge\n\n1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n"
my_input << "2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00\n\nMobile Number:,770-555-1213\n\nitem,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge\n\n"
my_input << "1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00\n\n"
lines = my_input.split("\n")
count = 0
cur_num = "" # Line 7 - Comment out this line to see failure
lines.each do |line|
unless (line.strip.eql?(""))
if (line.slice(0,15) == "Mobile Number:,")
cur_num = line.slice(15,12)
count = 1
puts "Current Number: #{cur_num}"
#puts "Object Type: #{cur_num.class}"
else
data = line.strip.split(',')
if (data.length > 8)
data.unshift(cur_num)
#if (count.modulo(10) == 0 || count == 1)
puts "[#{cur_num}] #{data.inspect}"
#pp data
#end
count += 1
end
end
end
end
如果我注释第7行,那么第18行和第20行的cur_val为零。
有人可以解释一下原因吗?