New with Null object doesn't throw exception

Archives Forums/BlitzMax Bug Reports/New with Null object doesn't throw exception

Tommo(Posted 2009) [#1]
BMax 1.34, Win32
Code below:
superstrict
framework brl.system

type testType
	field anyfield%
End Type


local o1:testType
local o2:testType

o1 = new testType
o2 = new o1
notify("ok")

o1 = null
o2 = new o1  'It's a error. But no exception given here, just crash.
notify("crash")



TaskMaster(Posted 2009) [#2]
The line:

o2 = new o1

is an error the first time you call it. You can't create a new of a variable. You just didn't get a crash because you hadn't tried to access it yet.


Tommo(Posted 2009) [#3]
This will create a new object of the same type as the variable put after New.
It's get compiled and running as you expected, so I'll take it as a feature.

And it's very useful, I'm using it very often as a solution to object template.


plash(Posted 2009) [#4]
is an error the first time you call it. You can't create a new of a variable. You just didn't get a crash because you hadn't tried to access it yet.
Incorrect.

Also, there certainly is no exception being thrown..
SuperStrict

Framework brl.blitz
Import brl.standardio

Type testType
	Field anyfield:Int
End Type

Local o1:testType
Local o2:testType

o1 = New testType
o2 = New o1
DebugLog("Good..")

o2.anyfield = 100123
Print(o2.anyfield)

Try
	o1 = Null
	o2 = New o1
Catch e:Object
	DebugLog("Exception caught: " + e.ToString())
End Try
DebugLog("Never reached!")



GW(Posted 2009) [#5]
your basically saying "o2 = new Null"

"o2 = new o1" is pretty neat though, i didn't know that was possible


TaskMaster(Posted 2009) [#6]
I wouldn't call that a feature, I would call it a bug. Being able to call:

o1 = New o2

is a bug.

Why do that, when you could just do it right and call:

o1 = New testType

???

It is a bug that you are taking advantage of, and when Mark Sibly fixes it, your apps will need to be fixed.

Is there an advantage to calling it the way you are?


plash(Posted 2009) [#7]
Is there an advantage to calling it the way you are?
Yes.

One simple example (creating a new instance of any given object):
SuperStrict

Framework brl.blitz
Import brl.standardio

Type testType
	Field anyfield:Int
End Type


Local o1:testType
Local o2:testType

o1 = New testType

o2 = testType(NewObject(o1))
o2.anyfield = 10
Print(o2.anyfield)

Function NewObject:Object(obj:Object)
	If obj <> Null
		Return New obj
	Else
		Return Null
	End If
End Function


I can see many uses for this 'feature'.


Brucey(Posted 2009) [#8]
Or perhaps :
Function NewObject:Object(obj:Object)
	If obj <> Null
		Return TTypeId.ForObject(obj).NewObject()
	Else
		Return Null
	End If
End Function

since "New obj" doesn't really make any sense.


TaskMaster(Posted 2009) [#9]
Hmmm, Plash, I still don't see it. Can you explain what that accomplishes?

If o1 had been null, then the o2.anyfield=10 would have been an error.

If o1 is not null, then you just get a new testType. But, since you know the type of object you are creating is a testType, why would you not do o2 = New testType ??


plash(Posted 2009) [#10]
If o1 is not null, then you just get a new testType. But, since you know the type of object you are creating is a testType, why would you not do o2 = New testType ??
The point is if you did not know. Perhaps if you wanted to provide a new instance of an object to some interface, which expected some specific result.

Perhaps simply creating a new instance of an object doesn't warrant that extensive amount of effort, but it could be tied in with other initialization workings as well..
Brucey's example is another way to do it.


Scienthsine(Posted 2009) [#11]
You -do- know. You declare the type of the variable before you ever do that assignment.
Local o1:testType
Local o2:testType

The only way that could even kinda work is if you changed the o2 declaration to object. This doesn't work however as blitz complains when you try to access a field of it.

After doing several tests with it just now, I can't find a way of using this where you don't already know the type of the object being assigned to. To use it in later code you would need to know anyway....

EDIT
You can cast the object to the type, and then access it's fields... but then you know the type. However... once again you know the type.

Ehhh... maybe it's not a bug, the compiler does state that the argument for new can be either a user created type or object... but it certainly isn't something I would ever encourage.


Tommo(Posted 2009) [#12]
I found this "feature" long time ago, before reflection was introduced.
I did always put a assert before creating object in this way, so I didn't encounter this "issue".

I was using it like:
function registerFruitTemplate(name$, fruit:tFruit) ...
function findFruitTemplate:tFruit(name$) ...
type tApple extends tFruit ...

registerFruitTemplate("apple", new tApple)

local somefruit:tFruit=new findFruitTemplate("apple")


As Brucey said, this can be done with reflection now. So this "feature" is not making sense any more.

If this is not a feature, then it's a bug of compiler to be sort out, and this post is still a bug report.

;)


Azathoth(Posted 2009) [#13]
Its a feature that existed before reflection.


TaskMaster(Posted 2009) [#14]
But, that is still not ANY different than:

local somefruit:tFruit = New tFruit

If your tApple extends tFruit, then it won't matter. someFruit can be a tApple or a tFruit.


Tommo(Posted 2009) [#15]
When you want a data-driven system, this will make sense.


TaskMaster(Posted 2009) [#16]
Hmmm...

Anything is possible I guess?!?!


plash(Posted 2009) [#17]
...