This is making me crazy. I'm trying to loop through email messages using ".each do |one_of|…end", but inserting one innocuous statement breaks the enumeration.
Here is an almost-stand-alone snippet. The authentication info is set up immediately preceding, as is the "require 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
It was working (and not) when I was looping through message ID numbers, but I replaced that statement with a literal array to eliminate a potential problem source.
Running it with the ".tr" statement commented out produces expected results, lines like:
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]
…
Now un-comment the ".tr" line, to remove the brackets, and it goes all the way through the first iteration, but then:
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)
So, somehow, putting this one statement in is causing the second iteration of mnum
to fail. It doesn't even print "2" for the second iteration. Line 45 in the traceback is the newly inserted statement, but it doesn't even get that far! Adding another puts
as the first statement in the inner loop does nothing.
I've done this before to concatenate a bunch of emails containing router log messages, but I then modified that code, and I somehow broke it! I've cut and re-typed the problem statement, thinking there may have been invisibles in there, but I'm using BBEdit, which shows such things.
Please, point out where I'm doing something stupid!
Thanks!
nil
prints as an empty string, so it's possible there is actually a last line which isn't matching the regexp and which is printing as an empty string. In that case, tr
would fail since nil
actually doesn't have a tr
method.
You could use a conditional assignment, which will not execute the right-hand side if recType
is falsy.
recType = line[/^\[.*\] /]
recType &&= recType.tr('[]','')
puts recType
Or (if you want to actually treat it as an empty string), you can simply unconditionally call to_s
on it.
recType = line[/^\[.*\] /].to_s
recType = recType.tr('[]','')
puts recType