#180931 - 2007-09-28 01:57 AM
Dynamically call Functions
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
I have a loop that CALLs all kix files in enabled folder. Each file contains a function. Function name is the name of the file.
/enabled/IE.kix /enabled/ENV.kix /enabled/NOTICE.kix
I am trying to dynamically call these functions with the function below. the CALL($EN) doesn't seem to call the corresponding function. I also tried $EN().
I can invoke them just fine with ENV() or CALL ENV
RUN_ENABLED("C:\Docume~1\iso\Desktop\KIX\Development\enabled")
Function RUN_ENABLED($path)
$runenabled = Dir("$path\*.*")
While $runenabled <> "" AND @ERROR = 0
If $runenabled <> "." AND $runenabled <> ".."
$EN=SUBSTR("$runenabled",1,LEN($runenabled)-4)
CALL($EN)
EndIf
$runenabled = Dir()
Loop
EndFunction
Any help would be appreciated! Thanks in advance.
Edited by iso (2007-09-28 01:59 AM)
|
|
Top
|
|
|
|
#180939 - 2007-09-28 09:52 AM
Re: Dynamically call Functions
[Re: Björn]
|
Richard H.
Administrator
   
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
Just as Bjorn says:
- You need to remember to include the path, otherwise the file will be local.
- You don't need to strip the suffix.
- CALL is a command, not a function.
Here is your code slightly modified - it should get you closer.
RUN_ENABLED("C:\Docume~1\iso\Desktop\KIX\Development\enabled")
Function RUN_ENABLED($path)
Dim $runenabled
$runenabled = Dir("$path\*.*")
While Not @ERROR
If $runenabled <> "." AND $runenabled <> ".."
Call $path+"\"+$runenabled
EndIf
$runenabled = Dir()
Loop
EndFunction
|
|
Top
|
|
|
|
#181034 - 2007-10-02 04:50 PM
Re: Dynamically call Functions
[Re: Richard H.]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
Each file (ie.kix, env.kix.. ) contains a function. Prior to this piece of code, these files have already been called and loaded into memory. Here I am trying to call the functions within the files. CALL ENV works if I hard code it in, however CALL $EN doesn't seem to work. The stripping is to retrieve the function names only.
Thanks for the clarifications!
|
|
Top
|
|
|
|
#181035 - 2007-10-02 05:04 PM
Re: Dynamically call Functions
[Re: iso]
|
Glenn Barnas
KiX Supporter
   
Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
|
Here's a block of code from my KGen utility, which locates all of the UDFs in the current and defined library folders. It creates an array of UDF name and the file it exists in. You can modify this to return a simple array of UDF names (since they are already loaded and you don't need to know WHERE they are).
It requires a $PATHS variable with the names of folders to search. You could probably add your CALL statement here, since the full path is defined. The advantage of this kind of code is that it will identify all of the UDFs in a file, not just the one based on the file name. Also - the file name and UDF name don't need to match.
Glenn
; Assemble a 2-dimensional array containing a list of function names and the files
; that hold them. Search the folders defined in the PATHS array
'Searching for available UDFs'
For Each $PATH in $PATHS
$File = Dir($Path + '\*.*')
While $File <> '' And @ERROR = 0
If Left($File, 1) <> '.'
If Right($File, 4) = '.udf' Or Right($File, 4) = '.kxf' Or $File = $SrcFile
If $PATH = '.' And $File <> $SrcFile ; automatically include everything in '.'
; If the .KXF/.UDF file is in the project folder (.), just include it
$FnFiles[$OP] = $PATH + '\' + $File ; add file to array of included files
$OP = $OP + 1
$ = RedirectOutput($LogFile)
' adding project file ' + $PATH + '\' + $File ?
$ = RedirectOutput('')
EndIf ; PATH = '.'
; open the file, read lines until 'function' is found in a non-comment area
; obtain the function name, and add the function name and file name to the array
If Open(3, $Path + '\' + $File, 2) = 0
$Line = Trim(ReadLine(3))
While @ERROR = 0
; Function definition must be in column 1 after trimming spaces to be considered valid
If InStr($Line, 'Function') = 1
; get rid of the 'function ' and split off the function name
$Fn = Trim(Split(SubStr($Line, 10), '(')[0])
$UDFNames = $UDFNames + $Fn + '(,'
$Functions[$FP,0] = $Fn
$Functions[$FP,1] = $PATH + '\' + $File
$FP = $FP + 1
If $FP Mod 8 = 0 '.' EndIf ; status indicator
EndIf
$Line = Trim(ReadLine(3))
Loop ; while not error
$ = Close(3)
EndIf ; Open
$FF = $FF + 1
EndIf ; .udf or .kxf file
EndIF ; not '.'
$File = Dir() ; get next file
Loop
Next ; $Path
? ' ' $FP ' UDFs located in ' $FF ' files.' ?
_________________________
Actually I am a Rocket Scientist!
|
|
Top
|
|
|
|
#181046 - 2007-10-02 08:31 PM
Re: Dynamically call Functions
[Re: Glenn Barnas]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
Sick! Thanks Glenn. This approach is much better.
|
|
Top
|
|
|
|
#181050 - 2007-10-02 10:15 PM
Re: Dynamically call Functions
[Re: Glenn Barnas]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
Glenn, is your site down?
|
|
Top
|
|
|
|
#181056 - 2007-10-02 11:28 PM
Re: Dynamically call Functions
[Re: Glenn Barnas]
|
NTDOC
Administrator
   
Registered: 2000-07-28
Posts: 11631
Loc: CA
|
bummer - you now make people register to download
|
|
Top
|
|
|
|
#181058 - 2007-10-03 12:30 AM
Re: Dynamically call Functions
[Re: NTDOC]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
I did some modifying of the code above and was still running into problem. So I did the following test.
This called the function loaded into memory.
CALL "C:\Docume~1\ana\Desktop\KIX\Development\enabled\NOTICE.kix"
$test = NOTICE
CALL $test
For some reason, this code doesn't.
Function RUN_ENABLED($path)
$count = 0
$runenabled = Dir("$path\*.*")
While $runenabled <> '' AND @ERROR = 0
If Left($runenabled, 1) <> '.'
If Right($runenabled, 4) = '.kix'
CALL "$path\$runenabled"
If Open(3,"$path\$runenabled",2) = 0
$Line = Trim(ReadLine(3))
While @ERROR = 0
If InStr($Line, 'Function') = 1
$Fn = Trim(Split(SubStr($Line, 10), '(')[0])
CALL $Fn
;CALL NOTICE
EndIf
$Line = Trim(ReadLine(3))
Loop
$ = Close(3)
EndIf
EndIf
EndIf
$runenabled = Dir()
Loop
EndFunction
Any help would be appreciated. Thanks!
Edited by iso (2007-10-03 12:38 AM)
|
|
Top
|
|
|
|
#181059 - 2007-10-03 01:57 AM
Re: Dynamically call Functions
[Re: iso]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
A little more messing around yield the following results.
If I put NOTICE in " ", it fails to call the function (NOTICE NOTICE)
? $Fn
$Fn = "NOTICE"
? $Fn
CALL $Fn
If I leave out " ", it's able to call the function (NOTICE -------)
? $Fn
$Fn = NOTICE
? $Fn
CALL $Fn
Edited by iso (2007-10-03 01:59 AM)
|
|
Top
|
|
|
|
#181066 - 2007-10-03 05:38 AM
Re: Dynamically call Functions
[Re: iso]
|
Glenn Barnas
KiX Supporter
   
Registered: 2003-01-28
Posts: 4402
Loc: New Jersey
|
Couple of quick things..
$test = NOTICE <= no quotes around NOTICE
Call "$path\$runenabled" <= variables in strings - would be better as Call $Path + '\' | $RunEnabled
Also, I guess you have something like
$MyPath = 'c:\somewhere\enabled'
Run_Enabled($MyPath) somewhere to call the function?
I've added some comments and debug statements to your code. Since you're only interested in .KIX files, I've eliminated the checks for "." and ".kix". Those were necessary in my example because I searched for .KXF and .UDF files.
Function RUN_ENABLED($path)
$count = 0
$runenabled = Dir($path + '\*.KIX')
While $runenabled <> '' AND @ERROR = 0
;;; If Left($runenabled, 1) <> '.'
;;; If Right($runenabled, 4) = '.kix'
'Loading ' $Path + '\' + $runenabled ' into memory' ?
CALL $path + '\' + $runenabled ; Load into memory
If Open(3,$path + '\' + $runenabled,2) = 0 ; open the function file
$Line = Trim(ReadLine(3)) ; read the line, remove all leading/trailing spaces
While @ERROR = 0 ; loop until EOF error
If InStr($Line, 'Function') = 1 ; does the line contain a Function declaration?
; Line should look like:
; 1234567890123...
; Function MyFunc(arg)
; so get the data starting at the 10th char and continue to the "(" char
$Fn = Trim(Split(SubStr($Line, 10), '(')[0])
'Calling ' $Fn ?
Execute ($Fn + '()' ; This string might need to be built to contain args.
;CALL NOTICE
EndIf
$Line = Trim(ReadLine(3)) ; Get the next line
Loop
$ = Close(3) ; done, close the input file
EndIf ; open success
;;; EndIf ; .kix file
;;; EndIf ; not a dir file
$runenabled = Dir() ; find next file
Loop
EndFunction
Adding diagnostic messages in your code is an important part of development. Without them, you can only guess as to what's happening. You might want to use a RedirectOutput statement so they are saved to a log file.
Another comment - "?" is not a shortcut for the "print" command like it is in BASIC. It's actually a shortcut for the CRLF - "?" and @CRLF are interchangable, and generally would occure AFTER the text is output, not before.
Also - a personal preference with a reason. I use single quotes to surround strings unless the string contains a contraction (like "can't"), when I use double quotes. The reason is that DOS commands usually require double quotes, so - if you Shell or Run O/S commands, you'll need to surround your commands in "'" so you can embed the " chars for the O/S commands.
Glenn
Edited by Glenn Barnas (2007-10-03 01:34 PM) Edit Reason: Adjusted for Richard's Execute correction
_________________________
Actually I am a Rocket Scientist!
|
|
Top
|
|
|
|
#181858 - 2007-10-23 03:37 PM
Re: Dynamically call Functions
[Re: Glenn Barnas]
|
iso
Fresh Scripter
Registered: 2007-06-29
Posts: 10
|
Thanks Richard. Your magic worked.
|
|
Top
|
|
|
|
Moderator: Jochen, Allen, Radimus, Glenn Barnas, ShaneEP, Ruud van Velsen, Arend_, Mart
|
1 registered
(Allen)
and 271 anonymous users online.
|
|
|