ToString() broken? removed? gone?

BlitzMax Forums/BlitzMax Programming/ToString() broken? removed? gone?

GfK(Posted 2006) [#1]
I use the following line in my code:
font.text "("+Len(w.txt).ToString()+")",x,y

It used to work perfectly. I've since updated to 1.22 and done Syncmods and now I get "Compile Error: Identifier 'ToString' not found". BLIde still highlights ToString() as if it still exists. I tried compiling in the standard IDE and I get the same error there, too.

What's the deal? Has ToString() been removed? I see no mention of it in the list of updates.


Gabriel(Posted 2006) [#2]
Try just casting to String with String(Len(w.txt) instead. You might not even need to cast, it might be automatic. I never used ToString so I'm not sure what happened to it.


GfK(Posted 2006) [#3]
Yeah, 'font.text "("+Len(w.txt)+")",x,y' is what I'm using now. Was just a bit surprised that it has apparently been removed without warning.


Azathoth(Posted 2006) [#4]
If it worked at all it was likely a bug, Len returns a number not an Object.
ToString hasn't been removed, it still works with Objects.


Fabian.(Posted 2006) [#5]
It's a bug in version 1.22.
The correct behaviour is that the member access operator is precedenced to the Len operator.
So "Len(anything).ToString()" has to be compiled as "Len((anything).ToString())".
But in version 1.22 somthing got wrong - so "Len (anything).ToString()" is compiled as "(Len(anything)).ToString()".
So the compiler thinks you want first to get the length of it and then access to the ToString method of the returned integer (which is impossible because there's no ToString method in type Int).
The correct compiler behaviour would be first to compile the access to the ToString method and then compile Len to get the length of the returned string.

To solve this I'm currently still using V1.20, but that's not a good solution.

I don't know when this gets fixed, but I hope very soon.


sswift(Posted 2006) [#6]

So "Len(anything).ToString()" has to be compiled as "Len((anything).ToString())".



Whaaaat?

Am I in bizzaro land?

It makes perfect sense to me that Len(Anything).ToString would perform the Len(Anything) operation first, and then do the ToString on whatever object was returned from Len().

Otherwise, I could not do this:
Text.Create(NewText$, 0, 0, 1, Board).Pivot.AnimatePosition(X#, Y#, X#, Y#-250, 1000)

Cause then instead of Pivot being a field of whatever object Create returns, it would try to act on this stuff: (NewText$, 0, 0, 1, Board)


If you want .ToString to act on what is in the brackets in Len, then why don't you just do this?

Len(anything.ToString())


GfK(Posted 2006) [#7]
If you want .ToString to act on what is in the brackets in Len, then why don't you just do this?

Len(anything.ToString())
Um, because its already a string? ;)

I'm pretty sure that I should be able to use ToString on any number. I can in VB/C#.


Mark Tiffany(Posted 2006) [#8]
I think the problem is that numbers in max aren't actually objects. I'm pretty sure mark said as much a while back, and hinted that they ought to be objects too...


Winni(Posted 2006) [#9]
> I think the problem is that numbers in max aren't actually objects.


Sounds like Java, where primitive datatypes are the only exception to the "everything is an object rule"...


sswift(Posted 2006) [#10]
"Um, because its already a string? ;)"

And how'm I supposed to know that when you didn't put the little $ on the end! :-)


Fabian.(Posted 2006) [#11]
sswift:
It makes perfect sense to me that Len(Anything).ToString would perform the Len(Anything) operation first, and then do the ToString on whatever object was returned from Len().
BlitzMax documentation: (in the "Expressions" section)
BlitzMax supports the following operators. Operators are grouped into levels of precedence, starting with the highest precedence operators:
.....


True                         True 
False                        False 
--------------------------------------------------------
Member access                Expression.Expression 
Index                        Expression[Subscripts] 
Invoke                       Expression(Parameters) 
--------------------------------------------------------
Negate                       - Expression 
Posate                       + Expression 

.....

Character code value         Asc Expression 
Character                    Chr Expression 
Length of value              Len Expression 
Size of value in bytes       SizeOf Expression 
Address of variable          Varptr Expression 

.....

Skidracer: (about this problem in the "BlitzMax Update V1.22 Up!" thread)
The precedence of the . (member access operator) is documented as being higher than the Len operator



Fabian.(Posted 2006) [#12]
sswift:
Otherwise, I could not do this:
Text.Create(NewText$, 0, 0, 1, Board).Pivot.AnimatePosition(X#, Y#, X#, Y#-250, 1000)
Of course you can do this because the operators with same precedence (which you're using) are complied from left to right.


sswift(Posted 2006) [#13]
I wasn't aware Len was an operator. I thought it just returned the length of strings like in every other language I've ever used. :-)


"The precedence of the . (member access operator) is documented as being higher than the Len operator"

So then:

"font.text "("+Len(w.txt).ToString()+")",x,y"


Should do (w.txt).ToString(), and Len should then operate on the resulting string.


I don't like this though. I code assuming Len() is a function because of years of conditioning. I see there that Asc and Chr are also operators now? WHY? Can you do Asc on anything other than a string? Can you convert anything BUT a number to a Chr$()? Why change things just for the sake of changing them and confusing the hell out of people when stuff doesn't work?

If "font.text "("+Len(w.txt).ToString()+")",x,y" doesn't work now, and it's because Len is now a function and the . no longer takes precedence, then I'm FINE with that. That's how I'd expect it to work.


Dreamora(Posted 2006) [#14]
The precedence of . is high, thats correct. Nearly highest after all

But there is no question about precedence in this problem

len(x.txt) is a function. It gets executed before ANY precedence questions come up at all.
And the return of this function (-> int) then is used to execute the following procedure. And as int is no object it fails. No mather if + is higher than . or . higher than boolean or anything.

Can't remember that it ever worked at all.

.ToString() is a method I never called anyway, as it is an implicitely called method on objects anyway if they are used in a string context and thus it does not make sense. (sure there are some that want to explicitely cast anything. To me only makes sense if the code is that messy that the variable type isn't clear when writting the code so you can prevent "wrong casts")
If you've used modern languages, you are used to not manually call this method anyway as it is one of the objects core methods and its the same in BM.


sswift(Posted 2006) [#15]
"len(x.txt) is a function."

Are you sure about that? Because that table posted up there by Fabian says it is an operator wit lower precendence than the . operator.


Gabriel(Posted 2006) [#16]
The docs say it's an operator. Not that the docs are never wrong, but in this instance, I'm pretty sure they're right.


H&K(Posted 2006) [#17]
Skid posted this in the 1.22 update up thread three days ago
http://www.blitzbasic.com/Community/posts.php?topic=62674#701278

Len is an operator not a function so the brackets rule does noto apply. The precedense of the . (member access operator) is documented as being higher than the Len operator so my gut feeling is Fabian has found a bug.
So why are we all arguing about it. Its a bug. But most importantly...when he said len(x.txt) is a function
Dream was definatly wrong ;) (Oh Joyoius day)

I assumed it was a function as well, and the above from skid was to tell me I was wrong. But it still means that Dream was wrong as well


Dreamora(Posted 2006) [#18]
hmm. ok thats strange.

I was quite sure, len used to be a function that returns the value of .length of the underlying object.

On the other hand, I never used it. I've used OO from day 1 of BM and with OO you don't use len.
You use .length on string as well as array to get its size and on that there is no question about precedence or its type as it is declared as int.


H&K(Posted 2006) [#19]
@Dream,

It shocked me as well, (And if you look at the two threads several other people). But hah, as it was pointed out "Len x" works, which it whouldnt if Len was a return Function, (well it doesnt work properly hence the bug)

I did exactly what you had done and told Fabian that he was wrong, but Skid pointed out that he was right. But hah great minds think alike, even when we're wrong.


Dreamora(Posted 2006) [#20]
Wrong yes.
Or we just assume consistency, where it isn't present. (Operators operate on something as their name already points out. But returning or even calculation length is no operation, its just a query thus no operator)


Hotcakes(Posted 2006) [#21]
As I said, it's weird.


Hotcakes(Posted 2006) [#22]
As I expertly said... it's weird.