[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Bug in ruby?

Josh Mr.

11/21/2006 3:16:00 AM

Well, I've spent the last hour or so debugging one of the stupidest
errors I have encountered with Ruby.

Let's see my code first:

[code]def parse(string, starting, ending)
istart = string.index(starting) + starting.length
iend = string.index(ending, istart)
return string.slice(istart, iend - istart)
end[/code]

This function is called about 13 times in my entire script. It breaks on
the last one with this error:

undefined method `+' for nil:NilClass

Now, I have debugged the living hell out of this application. It's
breaking on the first line, stating that starting.length is a nil object
and that it can't perform a + operator in a nil object. The string
that's getting passed into starting is:

buy_item.phtml?

I debugged the application and put a mark on the first line to examine
it in the following code:

[code]def parse(string, starting, ending)
length = starting.length
istart = string.index(starting) + length
iend = string.index(ending, istart)
return string.slice(istart, iend - istart)
end[/code]

And the debugger said that length was an int with the value of 15. Guess
what still happened? Got the exact same error with the + operator on a
nil object. Except that completely contradicts the fact that it's not
nil but it's an int with the value of 15.

I have spent the last hour trying hundreds of different forms of this
code and am getting the same exact error every time. I've come to the
conclusion that this must be some kind of bug in Ruby, I can not pull on
piece of logical evidence out of this.

So my last resort is you guru's here, what am I doing wrong? Is there
some kind of magical law I broke? This application needs to get done
tonight, and I really can't afford anymore time on this tiny little bug.
Thanks in advanced.

~ Alias

--
Posted via http://www.ruby-....

30 Answers

brabuhr

11/21/2006 3:24:00 AM

0

On 11/20/06, AliasX Neo <kamipride102@gmail.com> wrote:
> Well, I've spent the last hour or so debugging one of the stupidest
> errors I have encountered with Ruby.
>
> Let's see my code first:
>
> [code]def parse(string, starting, ending)
> istart = string.index(starting) + starting.length
> iend = string.index(ending, istart)
> return string.slice(istart, iend - istart)
> end[/code]
>
> This function is called about 13 times in my entire script. It breaks on
> the last one with this error:
>
> undefined method `+' for nil:NilClass
>
> Now, I have debugged the living hell out of this application. It's
> breaking on the first line, stating that starting.length is a nil object
> and that it can't perform a + operator in a nil object. The string
> that's getting passed into starting is:

Wouldn't it be string.index() that is Nil here:

string.index(starting).+(starting.length)

starting.length is a parameter to the '+' method being called on the
result of index().

Justin Collins

11/21/2006 3:27:00 AM

0

AliasX Neo wrote:
> Well, I've spent the last hour or so debugging one of the stupidest
> errors I have encountered with Ruby.
>
>
<snip>
> I debugged the application and put a mark on the first line to examine
> it in the following code:
>
> [code]def parse(string, starting, ending)
> length = starting.length
> istart = string.index(starting) + length
> iend = string.index(ending, istart)
> return string.slice(istart, iend - istart)
> end[/code]
>
> And the debugger said that length was an int with the value of 15. Guess
> what still happened? Got the exact same error with the + operator on a
> nil object. Except that completely contradicts the fact that it's not
> nil but it's an int with the value of 15.
>

+ is being called on string.index(starting) not length. I'd check to
make sure you aren't getting nil from that:

def parse(string, starting, ending)
p string.index(starting)
istart = string.index(starting) + length
iend = string.index(ending, istart)
return string.slice(istart, iend - istart)
end

Hope that helps.

-Justin

David Vallner

11/21/2006 6:42:00 PM

0

This is a subject line that's mildly infuriating. I wonder if I can
recall more than three threads of that name that actually were a bug in
Ruby after all in the past year, and the one that's in living memory was
from Ara, and (unsurprisingly) a very subtle issue where it took me
three reads to find out why it's wrong behaviour in the first place, not
a "method not working at all" issue.

If you're not a syntax lawyer, and / or haven't checked the
documentation for what you're using a code snippet in the first place,
I'd say odds are good it's a bug in your code due to some (maybe not
really) gotcha you overlooked. And in that case it would be better to
present a problem as such, and providing a more informative subject line
to boot.

Also:

def parse(string, start, ending)
string.match(/#{Regexp.escape(start)}.*(?=#{Regexp.escape(ending)}/)[0]
end

David Vallner

Charles Hixson

11/21/2006 9:21:00 PM

0

David Vallner wrote:
> This is a subject line that's mildly infuriating. I wonder if I can
> recall more than three threads of that name that actually were a bug in
> Ruby after all in the past year, and the one that's in living memory was
> from Ara, and (unsurprisingly) a very subtle issue where it took me
> three reads to find out why it's wrong behaviour in the first place, not
> a "method not working at all" issue.
>
> If you're not a syntax lawyer, and / or haven't checked the
> documentation for what you're using a code snippet in the first place,
> I'd say odds are good it's a bug in your code due to some (maybe not
> really) gotcha you overlooked. And in that case it would be better to
> present a problem as such, and providing a more informative subject line
> to boot.
>
> Also:
>
> def parse(string, start, ending)
> string.match(/#{Regexp.escape(start)}.*(?=#{Regexp.escape(ending)}/)[0]
> end
>
> David Vallner
>
>
There have been many that I thought were "bugs in Ruby", though mainly
in the error message produced rather than that the code should have done
what the person objecting thought it should have done.

I'll grant that good error messages are a hard problem, but I frequently
find them totally exasperating. E.g., if a loop isn't properly closed,
the error message should point to where it started rather than several
lines after the end of the program. (Well, perhaps this one's been
fixed. I don't remember encountering it recently. But if it hasn't
been, I consider it a bug in Ruby.)

In this case the bug was in the message not stating which variable had a
nil value. You may not think of it as serious, but he reports spending
several hours on it, and I'd call that a bug.

Remember, Ruby is being recommended to total neophytes as a good
language to start with. That means that good diagnostic error messages
are essential!


Paul Lutus

11/21/2006 9:26:00 PM

0

AliasX Neo wrote:

> Well, I've spent the last hour or so debugging one of the stupidest
> errors I have encountered with Ruby.

It is a stupid error, but to say it diplomatically, the responsibility
assignment is flawed.

/ ...

> I have spent the last hour trying hundreds of different forms of this
> code

Except the one shown below.

> and am getting the same exact error every time. I've come to the
> conclusion that this must be some kind of bug in Ruby, I can not pull on
> piece of logical evidence out of this.

That is because you are not thinking hard enough.

> So my last resort is you guru's here, what am I doing wrong?

You are not breaking the problem down sufficiently. As others have
commented, there are two operands for "+" and you have only looked at one
of them.

Do this:

length = starting.length
si = string.index(starting)
if(length != nil && si != nil)
istart = si + length
end

> Is there some kind of magical law I broke?

Yes, as a matter of fact, there is. You assumed there was a flaw in the
language before exhausting the more obvious possibility that the error is
your own.

> This application needs to get done
> tonight, and I really can't afford anymore time on this tiny little bug.

Famous last words.

--
Paul Lutus
http://www.ara...

Leslie Viljoen

11/21/2006 10:28:00 PM

0

On 11/21/06, Charles D Hixson <charleshixsn@earthlink.net> wrote:
> David Vallner wrote:
> > This is a subject line that's mildly infuriating. I wonder if I can
> > recall more than three threads of that name that actually were a bug in
> > Ruby after all in the past year, and the one that's in living memory was
> > from Ara, and (unsurprisingly) a very subtle issue where it took me
> > three reads to find out why it's wrong behaviour in the first place, not
> > a "method not working at all" issue.
> >
> > If you're not a syntax lawyer, and / or haven't checked the
> > documentation for what you're using a code snippet in the first place,
> > I'd say odds are good it's a bug in your code due to some (maybe not
> > really) gotcha you overlooked. And in that case it would be better to
> > present a problem as such, and providing a more informative subject line
> > to boot.
> >
> > Also:
> >
> > def parse(string, start, ending)
> > string.match(/#{Regexp.escape(start)}.*(?=#{Regexp.escape(ending)}/)[0]
> > end
> >
> > David Vallner
> >
> >
> There have been many that I thought were "bugs in Ruby", though mainly
> in the error message produced rather than that the code should have done
> what the person objecting thought it should have done.
>
> I'll grant that good error messages are a hard problem, but I frequently
> find them totally exasperating. E.g., if a loop isn't properly closed,
> the error message should point to where it started rather than several
> lines after the end of the program. (Well, perhaps this one's been
> fixed. I don't remember encountering it recently. But if it hasn't
> been, I consider it a bug in Ruby.)
>
> In this case the bug was in the message not stating which variable had a
> nil value. You may not think of it as serious, but he reports spending
> several hours on it, and I'd call that a bug.
>
> Remember, Ruby is being recommended to total neophytes as a good
> language to start with. That means that good diagnostic error messages
> are essential!

I have also previously requested that this get fixed in a future Ruby.
It's very annoying to try and guess which could be the offending
variable in a complex expression, and it wastes a lot of time. It
would surely be very easy for Ruby to say which variable was nil.

In some of my latest scripts I have this:

def preventNil(*args)
args.each_with_index do |arg, i|
raise ArgumentError.new("argument #{i} cannot be nil") if arg.nil?
end
end

class StatSaver
def initialize(vehicle, column, dataSet, log)

preventNil(vehicle, column, dataSet, log)

@vehicleID = vehicle.VehicleID
@column = column
@dataSet = dataSet
@log = log
end

...

...as a kind of firebreak contract to prevent nil's from failures in
completely unrelated places causing other code to fall over. You don't
always realise that a certain method might return nil.

I'd be interested to hear if there are nicer solutions to this problem.

Les

Paul Lutus

11/21/2006 10:30:00 PM

0

Charles D Hixson wrote:

/ ...

> I'll grant that good error messages are a hard problem, but I frequently
> find them totally exasperating. E.g., if a loop isn't properly closed,
> the error message should point to where it started rather than several
> lines after the end of the program.

But the interpreter cannot do that without reading the programmer's mind.
Maybe the programmer intended to complete the loop in some code, not yet
written, that extends beyond the present end of the program. The evidence
is that the interpreter's scanner ended up at the end of the file, still
happy with the syntax up to that point.

> (Well, perhaps this one's been
> fixed. I don't remember encountering it recently. But if it hasn't
> been, I consider it a bug in Ruby.)

It is not a bug in Ruby if the incomplete loop could in principle continue
beyond EOF.

> In this case the bug was in the message not stating which variable had a
> nil value. You may not think of it as serious, but he reports spending
> several hours on it, and I'd call that a bug.

It is not a bug, at least, not in Ruby. At the point at which the error
condition arises, the '+' method doesn't know the names of the variables
that produced its inputs, it only knows that one of them is nil. Remember
that this is a runtime error.

And the OP used a debugger but still didn't realize there was a possibility
he hadn't considered. This is not something any finite-sized language can
possibly deal with.

Also remember: in an interpreted language, every increase in hand-holding
runtime comprehensiveness decreases execution speed.

> Remember, Ruby is being recommended to total neophytes as a good
> language to start with. That means that good diagnostic error messages
> are essential!

It also means that, as in all computer programming for all time, neophytes
have to pay attention to details.

The single most difficult part of learning how to program is to fully grasp
how simple-minded computers actually are. Successful programmers know
exactly how a computer will react to their code. Learning this, reducing it
to a matter of instinct, takes time.

--
Paul Lutus
http://www.ara...

Jim Cochrane

11/22/2006 12:45:00 AM

0

On 2006-11-21, Paul Lutus <nospam@nosite.zzz> wrote:
> AliasX Neo wrote:
>
> ...
>
>> This application needs to get done
>> tonight, and I really can't afford anymore time on this tiny little bug.
>
> Famous last words.
>

So, how'd it go? Was it finished in time and under budget? :-)

--

Paul Lutus

11/22/2006 1:00:00 AM

0

Jim Cochrane wrote:

> On 2006-11-21, Paul Lutus <nospam@nosite.zzz> wrote:
>> AliasX Neo wrote:
>>
>> ...
>>
>>> This application needs to get done
>>> tonight, and I really can't afford anymore time on this tiny little bug.
>>
>> Famous last words.
>>
>
> So, how'd it go? Was it finished in time and under budget? :-)

I think the OP is a student, in any case someone who isn't that into
programming as recreation.

Professionals don't conceptualize program flaws as "this tiny little bug".
There is no such thing. All the tiny little bugs that weren't so tiny ...
the one that disabled a US Navy destroyer running NT (after someone entered
a zero into a user-level application and precipitated a divide-by-zero
error that brought down the entire network), which then drifted out of
control as the sailor geeks tried to restart the network. The bug that
caused the Airbus to fly into the trees during an air show low pass
(passengers on board).

The microcode bug that caused Intel processors to produce incorrect math
results, and damaged their reputation for a while.

The bug that cause Mars Polar Explorer to prematurely shut down its engine
and fall the last 100 meters to the surface of Mars, never to be heard from
again.

"Tiny little bug." No such thing.

--
Paul Lutus
http://www.ara...

David Vallner

11/22/2006 1:09:00 AM

0

Charles D Hixson wrote:
> In this case the bug was in the message not stating which variable had a
> nil value. You may not think of it as serious, but he reports spending
> several hours on it, and I'd call that a bug.
>

I'm not aware of a programming language that DOES report this. Remember
that a nil value can come out of a fairly complex expression instead of
a single variable, and that nil can have many variables bound to it at a
given moment. The bug was in the OP's code, plain and simple, it's not
the responsibility of the programming language to do in-depth diagnosis
of dangling pointer problems.

Also, in the OP, the error message was consistent to Ruby's semantics -
a NoMethodError on nil usually significates what a NPE in Java,
NullRefError in C#, or segfault in C would be. Since the undefined
method was #+, the culprit was the expression that a method of that name
was called on in that code snippet.

Ruby reported what happened consistently with its computation model
(failed method lookup, nil being a regular object), and where it
happened (with no less detail than any other programming language I've
worked with reports on null pointers).

Further diagnostics (why it could have possibly happened) is the role of
a static code analysis tool; since it's sooner or later guesswork it's
not the task of the interpreter itself.

Coding defensively and using sanity checks on the return value of #index
and other methods that may return nil would also have helped.

> Remember, Ruby is being recommended to total neophytes as a good
> language to start with. That means that good diagnostic error messages
> are essential!
>

As is learning the syntax rules and how to read the error messages.

Also, whoever makes that recommendation is a fool, and I'm not
responsible for him making that wrong recommendation. AFAIK, the Ruby
language presumes the programmer is a grownup, and there's a LOT of
running with scissors involved. The simplicity makes it easy to pickup,
but in my opinion it gets very difficult to hobble along with only basic
knowledge and get something working done as the emergent behaviours
"noone tells you about" bite you if you don't either delve deeper into
how stuff works to avoid those errors, or get a broader overview of
what's available to end up writing less code (e.g. replacing futzing
around with substrings with a RE.)

David Vallner