(analysis current as of Mathematica V11.0.1)
UnpackOptions
is a macro that provides a convenient notation for accessing option values within a function definition.
At definition time, it transforms a source macro expression of the form:
UnpackOptions[option1, option2]
into an expanded expression of the form:
{option1, option2} = OptionValue @ {"Option1", "Option2"}
Note how the actual option names are generated automatically from the variable names which will receive the option values. The first character of the option name will be capitalized unless the variable name starts with a "$" (which will be dropped from the option name).
Examples
Examples of UnpackOptions
can be found in numerous source files distributed with Mathematica. Here is one:
{ $InstallationDirectory, "SystemFiles", "Components"
, "MXNetLink", "Kernel", "DataIterators.m"
} // FileNameJoin // NotebookOpen
For instance, the definition of MXDataRandomizer
starts like this:
MXDataRandomizer[assoc_Association, OptionsPattern[]] := CatchFailure @ Scope[
UnpackOptions[context, dataType];
If[!AllSameBy[Values@assoc, Length], Panic["DifferentLengths"]];
...
If we load this package and inspect the in-memory definition of MXDataRandomizer
, we will find the expanded macro:
Needs["GeneralUtilities`"]
Needs["MXNetLink`"]
PrintDefinitionsLocal[MXDataRandomizer]
(*
MXDataRandomizer[assoc_Association, OptionsPattern[]] := Catch[
Block[{context, dataType, randIndices, randomizedAssoc},
{context, dataType} = OptionValue @ {"Context", "DataType"};
If[!AllSameBy[Values @ assoc, Length],
...
*)
Also note how the macro CatchFailure
expanded into a Catch
expression, and how the implicit scoping macro Scope
expanded into an explicit Block
construct.
[as an aside, the use of Block here instead of Module is very dodgy]
Viewing Macro Definitions
The definition of UnpackOptions
itself, along with many other macros, can be inspected by evaluating:
Needs["GeneralUtilities`"]
PrintDefinitions[MacroRules]
Ensuring Macros Get Triggered
Beware that macros are only expanded when they appear as the top-level head on the right-hand side of a definition. This limitation is due to the fact that macros are implemented as up-values on Set
, SetDelayed
and TagSetDelayed
.
Since UnpackOptions
is not useful as a top-level expression, it needs to be contained within another macro to be used effectively. In the case of MXDataRandomizer
it was contained within the body of the top-level macro CatchFailure
.
Should we not want to use other macros like CatchFailure
or Scope
, there is a convenient macro called UseMacros
that will do nothing but trigger macro expansion:
Options[f] = {A -> 10, B -> 20};
f[x_, OptionsPattern[]] :=
UseMacros @ Module[{a, b}, UnpackOptions[a, b]; {x, a, b}]
f[1]
(* {1, 10, 20} *)
UnpackOptions
in version 10.1.0. Would you please include the function definition in your question? I have an idea of what this may be for but I need to see more. $\endgroup$