sprintf

Monkey Forums/Monkey Programming/sprintf

luggage(Posted 2011) [#1]
Is there any kind of string formatting in Monkey? I'd like to be able to do something like...

sprintf(myString, "%04d", index );

and that gives me a string like "0001" and so on.

Thanks!


Samah(Posted 2011) [#2]
Unfortunately Monkey does not support varargs, so no. You could probably write your own to accept an array...
Local str:String = Format("%04d", [index])


Edit: you might have trouble with typecasting arrays though.

Edit #2: Mark, can we get some better autoboxing with Object? It'd be great to be able to do this:

Local o:Object = 3

And it assigns o = IntObject(3).

Similar with arrays:
Local o:Object[] = [3]

Should create an Object[] array with one element, being an IntObject.


luggage(Posted 2011) [#3]
Thanks. Bit of a gap that. Worked around it for now as I only needed the example given so manually pad it out.


Samah(Posted 2011) [#4]
I've added a simple sprintf implementation to Diddy. Unfortunately Monkey doesn't autobox to Object (please, Mark?), so you'll need to manually do it with the B() function (B stands for Box).
Print Format("%04d", B(index))

It doesn't do a lot of error checking right now, so be careful. :)

Edit:
Supported format types: %d (integer), %f (float), %c (character), %s (string), %S (uppercase string), %x (integer as hex), %X (integer as uppercase hex).
All types except %c support a width and optional right-alignment (specified with a minus).
All numeric types support a padding 0 (exclusive to right-alignment).
%f currently truncates floats rather than rounding them (I'll fix this eventually).


marksibly(Posted 2011) [#5]
Hi,

I'm a bit wary of this 'auto boxing to object' mainly because it would mean IntObject, FloatObject and StringObject would all become a core part of the language (which they currently aren't) - not necessarily a bad thing, but not something done lightly.

But in addition, if auto boxing just produces a plain 'Object', well, Objects aren't all that useful on their own and you're still left with the issue of having to work out what type of object it is, either with a 'suck it and see' downcast, or via some 'meta data' like your type tags plus a downcast. But perhaps I have this wrong - I haven't done much boxing stuff...

I'd actually be less wary of autoboxing to something 'useful' - like some kind of Variant object with ToInt, ToFloat etc methods. Perhaps this could be a base class of IntObject, FloatObject etc? Which is starting to sound like something that could be useful in interpreted Monkey...

But as far as the original question goes, I tend to think this approach...

Function Format$( value,precision=blah,flags=etc )
Function Format$( value#,precision=blah,flags=etc )
Function Format$( value$,precision=blah,flags=etc )

...and just concatenating results together is better anyway - more efficient, less confusing (I HATE those godamn printf docs!) and just plain more Monkey like.

Semi-related: another thing I was thinking of adding in the early days of Monkey was a simple kind of varargs mechanism. Basically, the idea was that if the last param of a function was an array, client code could specify the array without the need for [ and ]. So, Print could become...

Function Print( arg$[] )

...and could then be used with varargs, eg:

Print x
Print x,y,z

...not sure what print would insert between items, but you get the idea.


Samah(Posted 2011) [#6]
I haxored boxes.monkey to make them all extend an Autobox class, hoping Monkey would work its magic. Alas, no dice. That's probably the best option I think. Maybe you could call the class Primitive?

As for the Format overloads, that's fine, but oldschool coders will want printf-style. :)


luggage(Posted 2011) [#7]
@Samah: Excellent job on adding Format into Diddy, that looks spot on and will cover the vast majority of use cases.

I don't mind the overloaded method either, I just tend to use whatever an API gives me.


Samah(Posted 2011) [#8]
Followup:
It appears that if the arguments are defined as String instead of Object, Monkey will accept primitives without the need for a boxing wrapper function.
This will now work as expected:
Print Format("%d,%s,%05.1f", 1, "foo", 3.1415)
1,foo,003.1

Fixed in revision 324.
Edit: Remember that %% will escape a % character.