Mathematica Programming » Assorted Tricks

Villegas-Gayley (internal function overloads)

This is a way we can assign definitions to built-in functions cleanly. This takes advantage of a two main things, a conditional definition and the power of Block . We'll use it to overload how MessageName works.

 Unprotect@MessageName;
(MessageName[o_,a:Except["usage"]]/;!TrueQ@$recursionBreakingVariable):=
  If[
    MatchQ[o,object[_Association]],
    First[o][a],
    Block[{$recursionBreakingVariable=True},
      MessageName[o,a]
      ]
    ];
Protect@MessageName;

Now we can do fun things with the MessageName operator, ::

 object[<|"a"->b,"c"->d,"e"->f|>]::a
 b

Usually that would have thrown an error:

 abject[<|"a"->b,"c"->d,"e"->f|>]::a
Message::name: Message name MessageName[abject[Association["a"->b,"c"->d,"e"->f]],"a"] is not of the form symbol::name or symbol::name::language.
 MessageName[abject[Association["a"->b,"c"->d,"e"->f]],"a"]

And the reason we did this the way we did is because if we assigned some object to a variable, variable::a would give us something meaningless. See:

 variable=abject[<|"a"->b,"c"->d,"e"->f|>];
variable::a
 variable::a

But if it's an object it will be treated differently:

 variable=object[<|"a"->b,"c"->d,"e"->f|>];
variable::a
 b

And because of the structure of the overload, MessageName still works normally in every other case.

See Also: