Skip to content

@fredemmott fredemmott released this May 31, 2019

This class wraps a value inside an object - this can be useful to get byref-like semantics. For example:

$total = C\count($jobs);
$done = new Ref(0);
concurrent {
  await Vec\map_async(
    $jobs,
    async $job ==> {
      try {
        return await handle_job_async($job);
      } finally {
        // As `$done` is an object, the changes persist outside of this scope;
        // if `$done` were an integer, `$done++` would only modify a copy of
        // the local within the lambda scope.
        $done->value++;
      }
    },
  );
  await async {
    while($done->value < $total) {
      await \HH\Asio\usleep(1000 * 1000);
      await IO\request_output()->writeAsync(
        Str\format("Progress: %d/%d\n", $done->value, $total)
      );
    }
  };
};

It is usually best to refactor to avoid this class; for example:

  • use inout parameters
  • return values from lambdas instead of mutating values from inside lamdas
  • use C\reduce() or C\reduce_with_key() if a Ref is being used as an accumulator

There are cases like the above where Ref is the cleanest solution; you may also find Ref<vec<T>> to be preferable to Vector<T>, in order to use a consistent API and be more explicit about when a function is likely to mutate a container.

Assets 2
You can’t perform that action at this time.