Ruby 枚举有意外的第二遍

Ruby enumeration has unexpected second pass

这让我发疯。我正在尝试使用“.each do |one_of|...end”遍历电子邮件,但插入一个无害的语句会破坏枚举。

这是一个几乎独立的片段。身份验证信息紧接在前面设置,“要求 net/imap”

也是如此
imap = Net::IMAP.new(IMAP_server)
imap.authenticate('LOGIN', IMAP_login, IMAP_pass)
imap.select(IMAP_folder)
[1,2,3,5].each do |mnum|
#message_ids = imap.search(['SUBJECT', 'NETGEAR R7000 Log']).each do |mnum|
    puts(mnum)
    msg = imap.fetch(mnum, 'BODY[TEXT]')
    msg[0].values[1]['BODY[TEXT]'].each_line do |full_entry|
        line = String.new(full_entry)
        recType = line[/^\[.*\] /]
#       recType = recType.tr('[]','')
        puts recType
    end
    puts
    puts
end

当我循环遍历消息 ID 号时,它工作(但不工作),但我用文字数组替换了该语句以消除潜在的问题源。

运行 它与注释掉的“.tr”语句产生预期的结果,像这样的行:

1
[DHCP IP: (192.168.1.9)] 
[DoS attack: FIN Scan] 
[DHCP IP: (192.168.1.8)] 
[Admin login] 
[Admin login failure] 
[Admin login] 
[DHCP IP: (192.168.1.7)] 
[DHCP IP: (192.168.1.5)] 
[Time synchronized with NTP server] 
[Internet connected] 


2
[LAN access from remote] 
[LAN access from remote] 
[LAN access from remote] 
[UPnP set event: Public_UPNP_C3] 
[UPnP set event: Public_UPNP_C3] 
[UPnP set event: Public_UPNP_C3] 
…

现在取消对“.tr”行的注释,删除括号,它会一直执行到第一次迭代,但随后:

1
DHCP IP: (192.168.1.9) 
DoS attack: FIN Scan 
DHCP IP: (192.168.1.8) 
Admin login 
Admin login failure 
Admin login 
DHCP IP: (192.168.1.7) 
DHCP IP: (192.168.1.5) 
Time synchronized with NTP server 
Internet connected 
Traceback (most recent call last):
        4: from /Users/jan/bin/MassageNetgear.rb:39:in `<main>'
        3: from /Users/jan/bin/MassageNetgear.rb:39:in `each'
        2: from /Users/jan/bin/MassageNetgear.rb:43:in `block in <main>'
        1: from /Users/jan/bin/MassageNetgear.rb:43:in `each_line'
/Users/jan/bin/MassageNetgear.rb:45:in `block (2 levels) in <main>': undefined method `tr' for nil:NilClass (NoMethodError)

所以,不知何故,放入这个语句会导致 mnum 的第二次迭代失败。第二次迭代甚至不打印“2”。回溯中的第 45 行是新插入的语句,但它甚至没有到那一步!添加另一个 puts 作为内部循环中的第一条语句什么都不做。

我以前这样做是为了连接一堆包含路由器日志消息的电子邮件,但后来我修改了该代码,但我不知何故破坏了它!我已经剪切并重新输入了问题陈述,认为那里可能有不可见的东西,但我使用的是 BBEdit,它显示了这些东西。

请指出我哪里做错了什么!

谢谢!

nil 打印为空字符串,因此实际上可能有最后一行与正则表达式不匹配,并且打印为空字符串。在那种情况下,tr 会失败,因为 nil 实际上没有 tr 方法。

您可以使用条件赋值,如果 recType 为假,则不会执行右侧。

recType = line[/^\[.*\] /]
recType &&= recType.tr('[]','')
puts recType

或者(如果你真的想把它当作一个空字符串),你可以简单地无条件地调用它to_s

recType = line[/^\[.*\] /].to_s
recType = recType.tr('[]','')
puts recType