Using a nice answer https://mathematica.stackexchange.com/a/197936/42847 I got from a previous question I define:
ClearAll[MyData]
SetAttributes[MyData, HoldFirst]
MyData[stuff : Except[_Symbol]] :=
With[{evaluatedStuff = stuff},
Module[{storeVar = evaluatedStuff}, MyData[storeVar]] /;
AssociationQ[evaluatedStuff]];
I understand that when stuff argument is an association, a local variable is created (thanks to Module[...]
). This part is ok, demo:
MyData[<|"a" -> 1|>]
MyData[storeVar$7548]
Now let's say I want to compare two such structures:
No problem here:
q = <|"a" -> 1|>
MyData[q]==MyData[q]
True
A problem I understand
MyData[<|"a" -> 1|>] == MyData[<|"a" -> 1|>]
MyData[storeVar$7538] == MyData[storeVar$7539]
Here we use two different internal variables to store stuff argument and they are not evaluated because of the HoldFirst
attribute
So I introduce an overload for the Equal[]
operator:
MyData /: Equal[A_MyData, B_MyData] := First[A] == First[B]
and now:
MyData[<|"a" -> 1|>] == MyData[<|"a" -> 1|>]
True
works as expected.
Problem with VerificationTest[]
: now I want to do units tests:
VerificationTest[MyData[<|"a" -> 1|>], MyData[<|"a" -> 1|>]]
but I get an TestResultObject
with Failure Outcome!!
First question: Why and how to fix that? (maybe my way to define Equal[]
is not the right one?)
Second question:
More broadly speaking, when you write a MMA package using "structure" like MyData
, what is the good practice when defining stuff like:
Format[MyData[a_Symbol?AssociationQ]] := "Pretty print of MyData[]"
MyData /: MyData[data_Symbol?AssociationQ][s_String] := data[[s]];
To put then in the public section or in the private one?
BeginPackage["FooPackage`"];
MyData::usage="A structure ...";
... <- Format, Equal,... Here ?
Begin["`Private`"];
... <- Or here???
End[] (*Private *)
EndPackage[];
Options[VerificationTest, SameTest]
$\endgroup$