operator_compare throwing NilObjectException

dim t1 as NullableString = "hello" dim comparisonString as string = "hello" //Debugger now shows t1 as existing (not nil) if t1 <> comparisonString then //Program blows up here Break end
The program throws a NilObjectException on the “if t1 <> comparisonString then” line even though I know that nothing is nil.

Is this a bug?

My nullableString class only has a Value property of type string and the 3 following methods:

Function operator_compare(rhs as string) As integer If self.Value > rhs then Return 1 If self.Value = rhs then Return 0 If self.Value < rhs then Return -1 End Function

Function operator_convert() As String return Value End Function

Sub operator_convert(s as String) self.Value = s End Sub

Copied your code into a new project. It runs without a NilObjectException.

Ah, that’s because my actual code looks like this.

[code] dim t1 as NullableString = “hello”
dim t2 as NullableString

dim helper as string = “hello”
if helper <> t1 then
Break
elseif helper <> t2 then
break
end[/code]

The debugger was staying on the first “if” line and not jumping to the “elseif” line where the exception was actually being thrown.

Thanks for taking a look at this!

In your example, t2 is Nil. What behavior do you expect other than a NilObjectException?

This had more to do with the debugger showing me as still being on the first “If” line so I didn’t realize the NilObjectException was being thrown from the second “elseif” line.

Had the debugger moved to the “elseif” line and required me to hit the moveNext before throwing the exception I would have caught this right away.

Like this (rb 2015.r2.1 on OS X 10.9.5) and 2015r2 on Windows 7 ?

I have my break point set like this:

https://xojo.io/?dl=0

And if I click “Step” it immediately moves to this:
https://www.dropbox.com/s/6vbi158hliyidp0/Screen%20Shot%202015-06-01%20at%202.12.28%20PM.png?dl=0

It never gets to the elseif

2015r2.2 Mac OSX (10.10.3)

Here’s a video of it happening

https://www.dropbox.com/s/fg54fcmhusrnvpt/DubegNilObjectError.mov?dl=0

Remove the breakpoint.

That doesn’t fix the core problem. The problem is when you’re stepping through code it makes you think the exception is being thrown on a different line than it is. This made my error more difficult to track down and this is a problem with the IDE.

I just run your code with the breakpoint set and it stops on the IF, and when continuing it jumps to the ELSEIF and throws a runtime exception there. This is with 2015r2.2 on OS X 10.9.5.

Are you sure the error isn’t happening within the NullableString class on the line with the IF?

I posted a video of it happening:

[quote=191214:@Brock Nash]Here’s a video of it happening

Yes, I saw that. And my conclusion was – as the code runs correctly up to the ELSIF here – that maybe in the NullableString class you have by now more code than in your OP above and the NilObjectException is happening in Operator_Convert. Just a guess…

The problem is if you have this:

  if MyCondition1 then
    Break
  elseif mycondition2 then
    break
  elseif mycondition3 then
    break
  elseif mycondition4 then //Throws nilobjectexception
    break
  elseif mycondition5 then
    break
  end

Let’s say myCondition4 throws a nilobjectexception
If you’re stepping through code, it jumps over all these elseif conditions with a single step so you don’t know which one caused the exception.

Note: It does work if you turn Break On Exceptions on, but this typically is a feature that I can’t have turned on.

This will stop on ELSEIF:

dim helper as string = "hello" dim helper2 as string = "hello" if helper <> t1 then break elseif helper2 <> t2 then break end
So my conclusion is that the above (skipping elseif) is the correct behavior – due to compiler optimization.

dim t1 as NullableString = "hello" dim t2 as NullableString dim helper as string = "hello" if t1 <> helper then Break elseif t1 <> helper then Break elseif t1 <> helper then Break elseif t1 <> helper then Break elseif t2 <> helper then //this line will throw a nilObjectException Break elseif t1 <> helper then Break end

But when stepping through the above, it will not break on the elseif. It makes you think the error is in the line:

  if t1 <> helper then

But it isn’t…

Again, it seems that the compiler optimizes the code as long as BreakOnException is off. BreakOnException should be on when debugging.

Probably a moot point but Nil is not a nullable string so this code won’t likely work the way I expect Brock expects it to

  dim t2 as nullableString
  dim helper as string = "hello"
  
  if t2 is nil then // this does break
    break
  end if
  if t2 isa nullableString then // NO BREAK HERE t2 is NOT a nullableString
    break
  end if
  if t2 <> helper then // NIL (not a nil nullableString) compared to a string
    break
  end if
  if helper <> t2 then // string compared to NIL (not a nullableString nor a NIL nullableString - its NIL) 
    break
  end

And you cant extend the string type to get operator_compare control

But I can and i did.

The code works as long as you add a null check.

dim t1 as NullableString = "hello" dim t2 as NullableString dim helper as string = "hello" if t1 <> nil and t1 <> helper then Break elseif t2 <> nil and t2 <> helper then Break end

Extending the the operator_compare for string is done by adding methods through the other class not on string itself.
These 3 methods are added to the NullableString class.

The nullable type is working exactly as expected and you can pass it into any method just like a string.

Essentially you can use string and NullableString interchangeably with methods without needing an explicit cast!

The only thing that’s annoying is the “Step through” issue with the IDE not helping indicate which specific line is throwing the exception. It would also be nice is Nullable Object wrapper classes were included in the Xojo framework.