I was looking through some code I wrote last week.
At one point I am assigning an array which is stored on an object into an array property of a different object from a different class.
While i need to keep both objects around, I only need to keep the the second array reference around for a little while and when I’m done with it, need to get rid of it without affecting the array on the 1st object .
Without thinking I treated the array as I would an object and did:
Object2.theArray = NIL
Dim EmptyArray() as ArrayType
Object2.theArray = EmptyArray
The compiler did not complain and it seems to work (at least in the current Xojo version - I will also need to compile in an older version to support 10.6).
Are we supposed to be able to NIL arrays? Is it supported? If so has it always been supported? Is there any downside to NILing it vs assigning a new empty array?
While setting an array to nil is valid, I never do that because, the way I write my code, I never expect an array reference to be nil and would generate exceptions if I took up that practice. I would have gone with some variation of your second option.
[quote=161933:@Eli Ott]Beginning with version 2006 Release 4, Nil is a constant of its own datatype, not an Object. It can convert itself to any object class, any array type, or any of the pointer types (Ptr, WindowPtr, CString, PString, WString, and CFStringRef).
I never noticed that in the Docs (Probably because i started with RB long before that) … I always thought NIL was only for objects.
That said IMO there should be no such thing as a NIL array… It is counter intuitive (at least for us older folks who don’t think of Arrays as objects) and as Kem noted for a NIL array if you did
You would likely get a Nil object exception, which is REALY REALLY unintuitive and bug prone!
IMO Arrays (or at least their API facing us regardless of what is under the hood) should either fully BE objects requiring NEW or not behave like objects at all.
Nobody thinks of Xojo arrays as Object, they are pointers - and as the docs say, Nil is not an Object anymore but its own datatype and can be used for any non-scalar datatype (Object, arrays, Ptr, WindowPtr, CString, …).
A pointer does nor allocate (or deallocate) memory… It knows nothing of size. We also can not allocate a bock of memory AS raw memory and assign that address to an array.
And Array does know how much memory it as and can interpret the data in it only one way. I always thought of it as a data structure that under the hood uses pointers based on the indices passed… but with no direct external access to the pointer itself or the memory it points to… That is what MemoryBlocks are for.
Again the real issue is that once an Assay is NILed you can’t just ReDIM or even call UBound on it.
This makes the behavior of arrays neither fish note fowl and therefore unintuitive when NIL.
I’m not advocating that Arrays be objects. just that they not be allowed to be NIL.
[quote=161954:@Kem Tekinay]There is one very convenient use for this, and I wouldn’t want to lose the option. You can define a method like this:
Sub MyMethod (arr() As Something = nil)
This lets you tell the difference between a given empty array and no array given.[/quote]
Never thought of that…
For that reason it would nice to be able to assign and test for NIL for EVERY datatype. I most often come up against that for colors where all values make sense… I hate having to have a separate boolean to go along with a color.
I created classes for this like StringParam, BooleanParam, etc. I don’t think I did ColorParam, but that’s possible too. Using Operator_Convert, it’s easy enough to go back and forth with whatever the value is supposed to represent, and you can test for nil.
Your method would be defined something like:
Sub MyMethod (c As ColorParam = nil)
dim theColor as Color
if not ( c is nil ) then
theColor = c
theColor = defaultColor
I haven’t looked but this is supposed to be part of the new framework eventually too.
Certain types are values types not reference types
Color, integers, etc and there’s no opportunity to set them nil or test them for nil as theres no references involved
Now we COULD make EVERYTHing a reference type so you can test for nil on anything but I think people would be very upset with the commensurate hits since EVERY access would need to go through a pointer and this would probably hurt performance.
And every type would now be “ptr + space for the type” so things like integers which are now 32 bits would double in size.
[quote=162029:@Norman Palardy]Certain types are values types not reference types
I know and understand what you are saying…
[quote]Color, integers, etc and there’s no opportunity to set them nil or test them for nil as theres no references involved
That is a nice thing about passing a variant parameter… they CAN be NIL … but they cost in terms of memory, execution speed and loss of type checking.
I know but I often lament not having a “no value passed” default value for things like colors (with Numbers there often is a value that does not makes sense, and I use that)… I figure you guys could figure out some magic to deal with this that won’t cost anything!
For colors sometimes i define an “illegal” color that is unlikely to be really passed such as $c000100FF as the default, but it feels like a kludge.
Every color, integer etc is a “legal” value - although it ay be unlikely in YOUR app
There really is no way for us to decide that there is a flag value that would work for everyone in every situation
Its a 100% certainty that IF we decided on such a value someone would report a bug about this value
Its only illegal in your context - someone else might look at that & say “gee thats a perfectly fin color value”
Java has int and Integer - one a value type & one a Class based type you can instantiate by passing an int
They do this for all the basic type they support - there’s a value type based one & a class based one but quite honestly it confuses the heck out of most folks when they see it for the first time.
And there are most definitely implications as far as runtime & memory go.