Jump to content

can I make a user function with optional


adamgal
 Share

Recommended Posts

Have you tried using the #include functionality?

  Most of this could be solved in 10 seconds by coding a wrapper around the function / UDF that you don't need to configure all the parameters for, or that you expect to use the same arguments with each time:

Func DebugMsgBox($bugMsg)
   MsgBox(64, "Debug", $bugMsg, 10)
EndFunc

  With UDFs you can use this method with a C-language "OpenGL"-style naming convention to reflect the number of arguments you want to provide:

Func TheFunc($target, $manner)
  While 1
    If _Mangle($target, $manner) Then ExitLoop
  Wend
EndFunc

Func TheFunc1($target)
  While 1
    If _Mangle($target, "gently") Then ExitLoop
  Wend
EndFunc

Func TheFunc0($target, $manner)
  While 1
    If _Mangle("The world", "gently") Then ExitLoop
  Wend
EndFunc

<{POST_SNAPBACK}>

Thats not really viable. First, thats more work than just passing all the parameters every time. Second, it hard codes the "default" values in multiple places, where-as actually putting it in the one and only function definition hard codes it in one place (And a logical place to find and change it, too). Third, any future change to the function (Such as adding a new trailing optional parameter) instantly breaks code in multiple places (All the functions have to be recoded, and perhaps new ones added); however, having a way to specify that new trailing parameter is optional breaks no code as long as the order of the previously existing parameters isn't changed.

Wrapper functions have their uses, but attempting to emulate optional parameters isn't one of them because it very quickly becomes bulky and cumbersome to use.

Link to comment
Share on other sites

  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Thanks for you insight, Valik. I won't try to defend any viability of (the bad example of) the above method vs. C++ / Python-style optional parameters, which are undeniably elegant, and indeed this is the developer forum, not scripts & scraps...

I do think that an optional parameter functionality should simplify making UDFs, and that a C++ -style implemetation would do so.

Has anyone read code from another scripting language to see how they implement it?

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

I agree with Valik that should be more C++ like.

But as is, where is the problem with Larry workaround?

StringSplit gives you both how many arguments the user sent and using ReDim you can set more place in the array if the user didn't sent all parameters (or truncate if the user sent too much) and inizialize the values to everything needed.

If you need commas in you parameter use @lf, @cr or {tab}.

E.g.

;The user sent 5 value of max of 6
_MyFunc('a,b,c,d,e');Change for other tests.

Func _MyFunc($sParameters)
   $sc = ','
   
   Local $Arg, $c
   Local $Default1 = 'z', $Default2 = 'e', $Default3 = '3'
   Local $Default4 = 't', $Default5 = '4', $Default6 = 'n'
   
   $Arg = StringSplit($sParameters,$sc)
   ReDim $Arg[7];<- the number of parameters should be 6;
   
   If $Arg[0] < 6 Then
      For $c = 6 To $Arg[0] Step -1;   This loop never enter if the user
        ;                                 sent all parameters.
         $Arg[$c] = Eval('Default' & $c)
      Next
   EndIf
   $Arg[0] = 6
   For $c = 1 To 6
      MsgBox(4096 + 16, 'Argument ' & $c, $Arg[$c])
   Next
EndFunc  ;==>_MyFunc
Edited by ezzetabi
Link to comment
Share on other sites

Has anyone read code from another scripting language to see how they implement it?

TCL uses a parameter named "args" for this. Whenever the number of parameters does not fit but there's a parameter named "args" TCL puts all of the parameters that do not fit into this variable as a list (a special type of array in TCL).

Here's an example:

proc MyFunction { paramA paramB args paramC} {
# some code
}

MyFunction "sometext for A" "sometext for B" "this" "all" "goes" "into the args parameter" "and something for C"
MyFunction "sometext for A" "another for B" "this is for C"

Of course usually the args parameter is the last one, but that's the choice of the scriptwriter.

Link to comment
Share on other sites

The problem, ezzetabi, is delimeters with strings.

See here:

MyFunc('"This is a test of something, but I don't know what."' & @CRLF & 'var = ' & $myvariable & @CRLF & 'This could cause some problems')

Versus

MyFunc('"This is a test of something, but I don't know what."', 'var = ' & $myvariable , "This could cause some problems")

Also, no matter which delimeter you use, odds are you will have or need that delimeter in the string that you pass to the function, in which case you would need to rewrite the UDF.

Who else would I be?
Link to comment
Share on other sites

Oh this-is-me, that is more theorical than real.

Usually func need arguments that follows some rules and unused chars can find with easy. (Texts don't have non printable chars, files dont have @lf or some special simbols, ect.)

Tell me, without lies, how many times you needed the char 11 or 7 or even better the 22?

Ascii Table

I think I can guess the answer, never.

For a easier modification you can even set the char in the beginning of the func.

$sc = Chr(22)
$a = 'a' & $sc & 'b' & $sc & 'c' & $sc & 'd' & $sc & 'e'
_MyFunc($a)

Func _MyFunc($sParameters)
  Local $splitChar = Chr(22);The char


  Local $Arg
  Local $Default1 = 'z',$Default2 = 'e',$Default3 = '3'
  Local $Default4 = 't',$Default5 = '4',$Default6 = 'n'

  $Arg = StringSplit($sParameters,$splitChar)
[...]
Edited by ezzetabi
Link to comment
Share on other sites

The major downsides of the $sParameters approach as far as i can see are the overhead or splitting the params out (both in terms of time taken and lines of code spent), and then the pain of referring to them as array items (and the associated maintenance issues)

I have a catapult. Give me all the money or I will fling an enormous rock at your head.

Link to comment
Share on other sites

For simple C++ -like default argument behavior, would it work to capture cleaned-up token strings for the defaults during the parse process, save those with the other UDF data, and then insert any defaults needed just-in-time before/during an actual call to the UDF?

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

For simple C++ -like default argument behavior, would it work to capture cleaned-up token strings for the defaults during the parse process, save those with the other UDF data, and then insert any defaults needed just-in-time before/during an actual call to the UDF?

<{POST_SNAPBACK}>

We would also have to modify the section that checks that the number of arguments match the number in the UDF. Currenly one number is being stored, not a min and max that would be needed. Otherwise, I think that your method would be along the lines of what we would need to do.

Edit: Fix spelling misakes.

Edited by Nutster

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

Understood, Nutster. I'd be glad to have a go at this; I'll be working under time restrictions (= wife's tolerance) but I think I can have something to show fairly quickly.

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

@ezzetabi, I do use 21 a lot, but I haven't yet had an occasion to use 22. That is beside the point, as well. The main reason to have optional params is to save typing. If you have to type " & Chr(22) & " between each parameter instead of a comma, then you really don't save much, do you?

Edited by this-is-me
Who else would I be?
Link to comment
Share on other sites

(Forgot to mention)

This is not a problem anymore, my dear. Using a Opt() you can use:

$s = Chr(22)

$sArg ='My many$s$parameters$s$separed by a$s$chr22, with easy')

When do you need 21, by the way?

Edit: be sure... I'd like optional parameters too. But even without we can do what we want.

Edited by ezzetabi
Link to comment
Share on other sites

Finished the UDF validation adjustments portion of my test project, so that:= is permitted in the parameter list, if after a variable identifier

Constants and macros are permitted in the parameter list, if after an =

All parameters after the first with a default arg must have default args.

Also charted out some of the data members to be added like minumum parameters and a vector to hold the default argument tokens in the UDF details structure.

I've only got VC++ 5.0 so I had to jack with a few things (couldn't get the inline quick math to work), but I'll be able to isolate my tweaks before a code submission.

Edit: Any thoughts / insight about permitting AutoIt macros for default args? It was too easy to include them as valid tokens at the same time that constants (variant tokens) were. Is there any problem in doing so?

Edited by DaveF

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

  • Administrators

Pretty sure we already have the code for this somewhere when we came to exact same conclusion last time that we were going with the C++ way. It's just not been implemented because of time and priorites. And also when someone submits code that affects _everything_ I generally take a very close look at it which is why it never appears until I have time, or until I knock a version up myself that I can be less paranoid about :)

You can stop all the polls and discussions, it's all been decided before that when we add the optional thing it's the c++ way.

Link to comment
Share on other sites

Pretty sure we already have the code for this somewhere when we came to exact same conclusion last time that we were going with the C++ way.  It's just not been implemented because of time and priorites. And also when someone submits code that affects _everything_ I generally take a very close look at it which is why it never appears until I have time, or until I knock a version up myself that I can be less paranoid about :)

You can stop all the polls and discussions, it's all been decided before that when we add the optional thing it's the c++ way.

<{POST_SNAPBACK}>

The code is running on my side Func a(par1, ... oparn=value, ...) I am prepare to upload it to Jon. I add a @numpars in case we want to know the number of parameters which have been used inside the function :)
Link to comment
Share on other sites

You should not allow ByRef params to be optional. The default value would have to be a global variable (must be checked for), but I don't think that's a good idea.

In fact, a lot of checking and harder to evaluate that functions are called with correct number of arguments are some of the downsides of this proposed addition.

I still think a library function solution is sufficient. Check this out:

; Library funcs:

Func _Optional2(ByRef $sParams, $delimChar, ByRef $p1, ByRef $p2)
   If $sParams == $delimChar Then Return
   Local $a = StringSplit($sParams, $delimChar)
   $p1 = $a[1]
   If $a[0] >= 2 Then $p2 = $a[2]
EndFunc

Func _Optional3(ByRef $sParams, $delimChar, ByRef $p1, ByRef $p2, ByRef $p3)
   If $sParams == $delimChar Then Return
   Local $a = StringSplit($sParams, $delimChar)
   $p1 = $a[1]
   If $a[0] >= 2 Then $p2 = $a[2]
   If $a[0] >= 3 Then $p3 = $a[3]
EndFunc

; _Optional4, ...

; UDF with default values:

Func myFunc($sParams)
  Local $var1 = "Default1", $var2 = "Default2", $var3 = 0
  _Optional3($sParams, "|", $var1, $var2, $var3)
  MsgBox(0, "myFunc", $var1 & " " & $var2 & " " & $var3)
EndFunc

; Test

myFunc("Hello|No|200"); specify all
myFunc("Hello|No"); last param uses default value
myFunc("|"); all params uses default values

Note: the overhead here should not be a big issue, but maybe avoid using it for very frequently called funcs. A convention that "|" is normally used as delimiter character is a good idea.

Edited by tylo

blub

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...