Functions: Inout Parameters
Hack functions normally pass arguments by value. inout provides
"copy-in, copy-out" arguments, which allow you to modify the variable
in the caller.
function takes_inout(inout int $x): void {
$x = 1;
}
function call_it(): void {
$num = 0;
takes_inout(inout $num);
// $num is now 1.
}
This is similar to copy-by-reference, but the copy-out only happens when the function returns. If the function throws an exception, no changes occur.
function takes_inout(inout int $x): void {
$x = 1;
throw new Exception();
}
<<__EntryPoint>>
function call_it(): void {
$num = 0;
try {
takes_inout(inout $num);
} catch (Exception $_) {
}
// $num is still 0.
}
inout must be written in both the function signature and the
function call. This is enforced in the typechecker and at runtime.
Indexing with inout
In addition to local variables, inout supports indexes in value
types.
function set_to_value(inout int $item, int $value): void {
$item = $value;
}
function use_it(): void {
$items = vec[10, 11, 12];
$index = 1;
set_to_value(inout $items[$index], 42);
// $items is now vec[10, 42, 12].
}
This works for any value type: vec, dict, keyset or array. You
can also do nested access e.g. inout $foo[$y][z()]['stuff'].
Dynamic Usage
inout is a different calling convention, so dynamic calls will not
work with inout parameters. For example, you cannot use
meth_caller, call_user_func or ReflectionFunction::invoke.
unset on a inout parameter will set the value to null. This is
not recommended, and will raise a warning when the function returns.