HELP! New to Ruby and need to debug for work! Chomp! Error

Hi,

I programmed years before with .Net, Java, etc. and haven’t had any
exposure to Ruby yet. Since I have a background in CS, I can kinda
follow what’s going on but I’m stuck with this.

I have taken over support for a website within our company that allows
users to submit requests. When they submit a request, they are sent an
email through our Exchange server with the request details. I’m getting
an error in the Ruby code that sends the emails. Any help would be
appreciated.

I’ve attached a copy of the error and the ruby code where the error is
happening.

Thanks

So the gets called on your socket in readline is returning nil instead
of a string object, and getting #chomp! called on it?

def readline(f)
(l = f.gets).chomp!
puts "srv> " + l if $debug
l
end

What do you see if you change it to;

def readline(f)
l = f.gets
puts “srv> %s” % l if $debug
l.chomp!
l
end

?

Sam

Thanks for replying Sam. I just tried it and got the same error
message.

On Jan 27, 2011, at 3:11 PM, Doug B. wrote:

appreciated.

I’ve attached a copy of the error and the ruby code where the error is
happening.

Take a look at the docs here:

http://ruby-doc.org/core/classes/IO.html#M000920

The call to “f.gets” is trying to read the next string from the IO
object (in this case it’s a TCPSocket). The docs say you’ll get nil when
you hit EOF. You can’t call #chomp (or most other methods) on NilClass
without it throwing up its hands and exiting.

I’m assuming you are getting EOF here because the socket connection has
been interrupted or dropped. Perhaps a router or firewall change is
related? Alternately, perhaps the peer (the guy on the other end of this
socket) is sending malformed messages. This is hard to debug without
knowing all of the pieces.

cr

Have you got the debug flag turned on, and does it output anything to
the console? I would expect it to say something like;

srv> nil

… in which case the socket gets method is returning nil for whatever
reason. If you just wanted to ignore it, you could have it return an
empty string or something if l == nil and see what breaks further down
the line. Maybe the socket connection is going away, or there is nothing
more to read off the socket? I’m not familiar enough with Ruby’s socket
libraries or the Classes/ Methods therein sorry.

def readline(f)
l = f.gets
puts “srv> %s” % l if $debug
if l.kind_of?(String)
l.chomp!
end
l
end

Sam

On Thu, Jan 27, 2011 at 4:56 PM, Sam D. [email protected]
wrote:

Have you got the debug flag turned on, and does it output anything to the
console? I would expect it to say something like;

srv> nil

nil.to_s returns an empty string, you probably want %p in your format
string
(or just use inspect)

On Fri, Jan 28, 2011 at 5:11 AM, Doug B.
[email protected] wrote:

http://www.ruby-forum.com/attachment/5800/GPID_Error_doc_1-25.doc
http://www.ruby-forum.com/attachment/5801/Copy_of_gpid_mail_utils.rb

refine your code.

1 you assume that gets always return something other than nil
2 if you accept nils, then convert it first to string before chomping
it or whatever…

best regards -botp

On Fri, Jan 28, 2011 at 5:03 AM, botp [email protected] wrote:

On Fri, Jan 28, 2011 at 5:11 AM, Doug B. [email protected] wrote:

http://www.ruby-forum.com/attachment/5800/GPID_Error_doc_1-25.doc
http://www.ruby-forum.com/attachment/5801/Copy_of_gpid_mail_utils.rb

refine your code.

1 you assume that gets always return something other than nil
2 if you accept nils, then convert it first to string before chomping
it or whatever…

Even better: drop method readline completely and use a loop with block:

def send_mail(to, subj, msg, filename=“”)

# establish socket
s = TCPSocket.new($host, $port)

ntlm = false

# handle host greeting
readline s
writeline s, "EHLO #{$host}"
s.each |line|
  line.chomp!
  ntlm ||= /^250-AUTH.+NTLM.*/ =~ line
  break if /^250 / =~ line
end

Note also that you then must declare variable “ntlm” outside the loop
body.

You also need to change the way you work with the socket because it
will only be properly closed if all goes well. Your current code will
leak open sockets in case of errors and may eventually run out of file
descriptors if this is running longer. You either need to do

# establish socket
s = TCPSocket.new($host, $port)
begin
  ...
ensure
  s.close
end

or simply use TCPSocket.open with block:

TCPSocket.open($host, $port) do |s|

end

Kind regards

robert