www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Set optional function parameter

reply Andrey <saasecondbox yandex.ru> writes:
Hello,
In D there is a nice function:
 auto Tuple!(int,"status",string,"output") executeShell (
  scope const(char)[] command,
  const(string[string]) env = cast(const(string[string]))null,
  Config config = cast(Config)0,
  ulong maxOutput = 18446744073709551615LU,
  scope const(char)[] workDir = null,
  string shellPath = nativeShell()
)  trusted;
It has got 5 optional parameters. For example I want set only the fifth and all other leave with default values. If it was C/C++ then I would write:
 executeShell("my_command", nullptr, 0, 18446744073709551615, 
 nullptr, "my/path");
Long and boring... What about D? Does it support something like this:
 executeShell("my_command", shellPath = "my/path");
or
 executeShell("my_command", default, default, default, default, 
 "my/path");
I mean - can I skip some arguments and set only one that I want? Hm, Python, it seems to me, support this feature.
Aug 17 2018
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, August 17, 2018 2:52:53 AM MDT Andrey via Digitalmars-d-learn 
wrote:
 Hello,

 In D there is a nice function:
 auto Tuple!(int,"status",string,"output") executeShell (

  scope const(char)[] command,
  const(string[string]) env = cast(const(string[string]))null,
  Config config = cast(Config)0,
  ulong maxOutput = 18446744073709551615LU,
  scope const(char)[] workDir = null,
  string shellPath = nativeShell()

)  trusted;
It has got 5 optional parameters. For example I want set only the fifth and all other leave with default values. If it was C/C++ then I would write:
 executeShell("my_command", nullptr, 0, 18446744073709551615,
 nullptr, "my/path");
Long and boring... What about D? Does it support something like this:
 executeShell("my_command", shellPath = "my/path");
or
 executeShell("my_command", default, default, default, default,
 "my/path");
I mean - can I skip some arguments and set only one that I want? Hm, Python, it seems to me, support this feature.
The short answer is no. D is more like C++ or Java in this respect. Python has named arguments, which allow you to indicate which parameter an argument goes with by name rather than by position, thus allowing you to skip giving values for some parameters if they have default values, whereas most C-derived languages - including D - do not have such a feature. Usually, it's a non-issue, because having more than one - maybe two - default arguments is pretty rare, and having long parameter lists is usually considered bad design. Unfortunately, executeShell is one of the few cases in Phobos where a function has quite a few parameters, and D does not directly provide a way to skip any parameters when providing arguments so that you can provide a value for an argument later in the parameter list while not providing parameters earlier in the list. There have been some templated solutions floating around from time to time to allow folks to implement a form of named arguments themselves, but as I've never done anything with them, I don't know if they're designed to help you in a situation like this or if they're designed such that the person who writes the function can give you a way to use named arguments with that particular function. You may find something floating around on code.dlang.org that would help you. However, if you're calling executeShell more than once, you could simply create a wrapper function that only had the parameters you wanted and then passed the full list of arguments to executeShell. - Jonathan M Davis
Aug 17 2018
prev sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Friday, 17 August 2018 at 08:52:53 UTC, Andrey wrote:
 I mean - can I skip some arguments and set only one that I want?
 Hm, Python, it seems to me, support this feature.
There's no such built-in functionality in the language or standard library, no. As Jonathan pointed out, this has been implemented as a template multiple times, though. Here's my version: https://gist.github.com/Biotronic/fffa7d4c96d760da5129d27ba3307f73 Usage: named!executeShell("my_command", args.workDir = "my/path") Missing functionality: No support for overloads. Sorry. No handy suggestions for which argument you may have meant when a typo sneaks in. -- Simen
Aug 18 2018