Passing list of arbitrary function arguments in Haxe
Asked Answered
T

4

8

In ActionScript I can use ... in a function declaration so it accepts arbitrary arguments:

function foo(... args):void { trace(args.length); }

I can then call the function passing an array:

foo.apply(this, argsArray);

I'd like to call the function with arguments of unknown type and count. Is this possible in Haxe?

Tarkany answered 7/2, 2015 at 19:50 Comment(0)
M
4

Starting with Haxe 4.2, Haxe will have native support for rest arguments:

function f(...args:Int) {
    for (arg in args) {
        trace(arg);
    }
}

f(1, 2, 3);

...args:Int is simply syntax sugar for rest:haxe.Rest<Int>. Only the last argument of a function can be a rest argument.

You can also use ... to "spread" an array when calling a function with a rest argument:

final array = [1, 2, 3];
f(...array);
Midtown answered 19/12, 2020 at 15:35 Comment(0)
S
7

According to the Haxe documentation, you can use a Rest argument:

If the final argument of a macro is of type Array<Expr> the macro accepts an arbitrary number of extra arguments which are available from that array:

import haxe.macro.Expr;

class Main {
  static public function main() {
    myMacro("foo", a, b, c);
  }

  macro static function myMacro(e1:Expr, extra:Array<Expr>) {
    for (e in extra) {
      trace(e);
    }
    return macro null;
  }
}
Syracuse answered 7/2, 2015 at 20:13 Comment(1)
This is the correct answer if you are wanting to write your own method that takes an arbitrary number of arguments. Not every Haxe compiler target supports "Rest" arguments, but you can emulate it at compile time using macros.Harmonist
P
6

You could use Reflect.callMethod():

class Test {
    static function main() {
        var console = js.Browser.window.console;
        var fn = console.log;
        Reflect.callMethod(console, fn, [1, 2, "three", [4]]);
    }
}
Phenomenal answered 7/2, 2015 at 20:48 Comment(1)
This is the correct answer if you are calling an existing method (in a native environment or an extern) which can take an arbitrary number of arguments.Harmonist
M
4

Starting with Haxe 4.2, Haxe will have native support for rest arguments:

function f(...args:Int) {
    for (arg in args) {
        trace(arg);
    }
}

f(1, 2, 3);

...args:Int is simply syntax sugar for rest:haxe.Rest<Int>. Only the last argument of a function can be a rest argument.

You can also use ... to "spread" an array when calling a function with a rest argument:

final array = [1, 2, 3];
f(...array);
Midtown answered 19/12, 2020 at 15:35 Comment(0)
A
3

Just to add to this, if you're describing an extern for an external JavaScript library (or Python, Lua, or any target language that supports the rest parameter, e.g. ...rest), there is a specific Haxe type, haxe.extern.Rest, to express this.

Here's an example showing that the JavaScript Math.max function handles varargs: http://try.haxe.org/#4607C

class Test {
  static function main() {
    trace("JS Math.max takes varargs:");
    trace(MyMath.max(1,2,3,4)); // 4
    trace(MyMath.max(5,6));     // 6
  }
}

@:native("Math")
extern class MyMath {
  static function max(a:Float,
                      b:Float,
                      rest:haxe.extern.Rest<Float>):Float;
}

Note that the Haxe standard library does not define Math.max with Rest, as its goal is cross-platform compatibility.

Affairs answered 19/12, 2015 at 21:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.