New with Null object doesn't throw exception
Archives Forums/BlitzMax Bug Reports/New with Null object doesn't throw exception
| ||
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") |
| ||
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. |
| ||
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. |
| ||
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!") |
| ||
your basically saying "o2 = new Null" "o2 = new o1" is pretty neat though, i didn't know that was possible |
| ||
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? |
| ||
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'. |
| ||
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. |
| ||
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 ?? |
| ||
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. |
| ||
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. |
| ||
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. ;) |
| ||
Its a feature that existed before reflection. |
| ||
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. |
| ||
When you want a data-driven system, this will make sense. |
| ||
Hmmm... Anything is possible I guess?!?! |
| ||
... |