PDA

View Full Version : thinBASIC calling function with name defined using string expression



ErosOlmi
18-03-2007, 09:15
Below post was taken from codingmonkeys (http://www.codingmonkeys.com) forum where Petr posted this nice example on how to use CALL statement for advanced dynamic function calling.

_________________________________________________

Hi,

I'd like to present you one of features which is present in thinBASIC for longer timer, but can be easily over-looked.

Imagine situtation, when you need to call various functions, depending on some condition.
For example, when you want to load some data from various file formats.

So first you will create multiple functions to handle each format:


FUNCTION Load3DS( FileToLoad AS STRING ) AS LONG
' Processing code here
END FUNCTION

FUNCTION LoadOBJ( FileToLoad AS STRING ) AS LONG
' Processing code here
END FUNCTION

FUNCTION LoadM15( FileToLoad AS STRING ) AS LONG
' Processing code here
END FUNCTION

.
.
.



Now you can handle this in thinBASIC like:


IF FileExtension$ = "3DS" THEN
Load3DS( FileName$ )
ELSEIF FileExtension$ = "OBJ" THEN
LoadOBJ( FileName$ )
ELSEIF FileExtension$ = "M15" THEN
LoadM15( FileName$ )
.
.
.
END IF

Lot of typing, isn't it?
So what about:


SELECT CASE FileExtension$
CASE "3DS"
Load3DS( FileName$ )

CASE "OBJ"
LoadOBJ( FileName$ )

CASE "M15"
LoadM15( FileName$ )

.
.
.
END SELECT

This looks better, probably executes even faster ...
But what about doing all this in one line ?

As you can see, I named the functions like "Load<FormatExtension>".
So there is nothing simplier than taking advantage of powerfull CALL keyword:


CALL "Load"+FileExtension$( FileName$ ) To ReturnValue


... simple isn't it ? thinBASIC resolves the name of function at run time and no need for multiline IFs or even SELECT case.
In case the function doesn't exists, thinBASIC produces run-time error and informs you about the problem.

Bye,
Petr

kryton9
18-03-2007, 09:31
Thanks for refreshing our memories about that Eros. I had forgotten about this powerful feature!!

Michael Hartlef
18-03-2007, 09:58
Thanks,

that is one of the big advantages that intepreted languages have. That is such a cool feature.

ReneMiner
10-03-2013, 15:55
Just to dig it out and to remind all users on this great thinBasic feature - it's currently one of my favourites.

It allows me cool stuff like powerful fast 'n easy handling of GUI-Elements:

every of my self created controls ("Gadgets") gets a Style-String like "MenuItem" or "Button"
and I can use this string not just to differ the Gadgets purposes but also this



Call "GADGET_Draw" + Gadget(Index).Style (Index)
'or
Call "GADGET_Click" + Gadget(Index).Style (Index)

my Subs-names read then:


Sub GADGET_ClickButton(Byval Index as Long)
Sub GADGET_ClickMenuItem(byval Index as Long)
Sub GADGET_Drawbutton(Byval Index as Long) ' UCase or LCase ?
Sub GADGET_Drawmenuitem(byval Index as Long) ' no worry, does not matter


Isn't there a way to take advantage of this in regular "UI" to make those Callbacks somehow appear more easier and clearly to read?
I think it would need some constant String-Array for all possible CB-messages which combine messagename + events name + the controls name to a subs name and just calls it if Function_Names() finds that - but I don't even get the normal callbacks together...

ErosOlmi
10-03-2013, 19:14
Something for the future :D

ReneMiner
14-03-2013, 19:34
Extended ways to use this feature:
Imagine a drawing app where you have tools as Pencil, Brush, Eraser...
obvious that the "Click" and "MouseLOn"(=holding left button) already get handled somehow as described above so I omit that...



Type t_Gadget
Style as String
Tag as String

' ... lots more...
End Type

Dim Gadget(123) as t_Gadget
Dim CurrentTool as Long
' ...
Gadget(%g_Painting).Style = "Painting"
Gadget(%g_Painting).Tag = bar + foo
' ...
Gadget(%g_toolbtnBrush).Style = "Toolbutton"
Gadget(%g_toolbtnBrush).Tag = "Brush"
Gadget(%g_toolbtnPencil).Style = "Toolbutton"
Gadget(%g_toolbtnPencil).Tag = "Pencil"
Gadget(%g_toolbtnEraser).Style = "Toolbutton"
Gadget(%g_toolbtnEraser).Tag = "Eraser"
' ...

Sub ClickToolbutton(ByVal Index as Long)
' uncheck current tool-image somehow visually
' and check the new one (Index) - won't write it here...
' then just
CurrentTool = Index
End Sub

' ...
Sub MouseLOnPainting(ByVal Index as Long, ByVal X as Long ByVal Y as Long)

Call_IfExists "WorkWith" + Gadget(CurrentTool).Tag (Index, X, Y)

End sub
' ...
Sub WorkWithBrush(Byval Index as Long, Byval X as Long, Byval Y as Long)
Sub WorkWithPencil(Byval Index as Long, Byval X as Long, Byval Y as Long)
Sub WorkWithLines...
Sub WorkWithEraser...
' ...