Skip to main content
Format/Interpretation has weird scoping issues; change to MakeBoxes/InterpretationBox instead; added 29 characters in body; added 1 characters in body
Source Link
Oleksandr R.
  • 23.2k
  • 4
  • 88
  • 129

A more object-oriented approach may be helpful here. For example:

BeginPackage["example`"]; thing; new; Begin["`Private`"]; thing /: new[thing[contents_]] := Module[{thing}, (* Supported operations: *) thing /: Plus[thing[x_], y_] := thing[x + y]; thing /: Times[thing[x_], y_] := thing[x y]; (* Example invalid operation: *) thing /: Power[_thing, _] := $Failed; (* Format value: *) thing /: Format[thingMakeBoxes[thing, StandardForm] =  Interpretation[ToExpression["example`thing"]InterpretationBox["thing", thing]; (* Return symbol: *) thing[contents] ]; End[]; EndPackage[]; 

Now we can write, e.g,

myThing = new@thing[73]; 4 myThing + 3 

which gives:

thing[295] (* == thing[4 * 73 + 3] *) 

However, despite the displaystandard form (which can also be copied and pasted from output to input thanks to the InterpretationInterpretationBox), the internal representation is quite different:

% // InputForm (* -> thing$576[295] *) 

As a result we can't just conjurconjure things up without invoking new, as the methods defined on real things simply won't exist in that case:

myNewThing = thing[48]; myNewThing + 17 (* 17 + thing[48] *) 

Strictly speaking, the format value would have been enough to answer your question as stated. However, it seems like an object oriented approach is quite a natural fit for what you're probably trying to achieve here, so the extra effort may be worthwhile for maintainability and robustness reasons if you intend to have a lot of different objects each with their own private methods and/or internal state.

A more object-oriented approach may be helpful here. For example:

BeginPackage["example`"]; thing; new; Begin["`Private`"]; thing /: new[thing[contents_]] := Module[{thing}, (* Supported operations: *) thing /: Plus[thing[x_], y_] := thing[x + y]; thing /: Times[thing[x_], y_] := thing[x y]; (* Example invalid operation: *) thing /: Power[_thing, _] := $Failed; (* Format value: *) thing /: Format[thing, StandardForm] =  Interpretation[ToExpression["example`thing"], thing]; (* Return symbol: *) thing[contents] ]; End[]; EndPackage[]; 

Now we can write, e.g,

myThing = new@thing[73]; 4 myThing + 3 

which gives:

thing[295] (* == thing[4 * 73 + 3] *) 

However, despite the display form (which can also be copied and pasted thanks to Interpretation), the internal representation is quite different:

% // InputForm (* -> thing$576[295] *) 

As a result we can't just conjur things up without invoking new, as the methods defined on real things simply won't exist in that case:

myNewThing = thing[48]; myNewThing + 17 (* 17 + thing[48] *) 

Strictly speaking, the format value would have been enough to answer your question as stated. However, it seems like an object oriented approach is quite a natural fit for what you're probably trying to achieve here, so the extra effort may be worthwhile for maintainability and robustness reasons if you intend to have a lot of different objects each with their own private methods and/or internal state.

A more object-oriented approach may be helpful here. For example:

BeginPackage["example`"]; thing; new; Begin["`Private`"]; thing /: new[thing[contents_]] := Module[{thing}, (* Supported operations: *) thing /: Plus[thing[x_], y_] := thing[x + y]; thing /: Times[thing[x_], y_] := thing[x y]; (* Example invalid operation: *) thing /: Power[_thing, _] := $Failed; (* Format value: *) thing /: MakeBoxes[thing, StandardForm] = InterpretationBox["thing", thing]; (* Return symbol: *) thing[contents] ]; End[]; EndPackage[]; 

Now we can write, e.g,

myThing = new@thing[73]; 4 myThing + 3 

which gives:

thing[295] (* == thing[4 * 73 + 3] *) 

However, despite the standard form (which can also be copied and pasted from output to input thanks to the InterpretationBox), the internal representation is quite different:

% // InputForm (* -> thing$576[295] *) 

As a result we can't just conjure things up without invoking new, as the methods defined on real things simply won't exist in that case:

myNewThing = thing[48]; myNewThing + 17 (* 17 + thing[48] *) 

Strictly speaking, the format value would have been enough to answer your question as stated. However, it seems like an object oriented approach is quite a natural fit for what you're probably trying to achieve here, so the extra effort may be worthwhile for maintainability and robustness reasons if you intend to have a lot of different objects each with their own private methods and/or internal state.

Source Link
Oleksandr R.
  • 23.2k
  • 4
  • 88
  • 129

A more object-oriented approach may be helpful here. For example:

BeginPackage["example`"]; thing; new; Begin["`Private`"]; thing /: new[thing[contents_]] := Module[{thing}, (* Supported operations: *) thing /: Plus[thing[x_], y_] := thing[x + y]; thing /: Times[thing[x_], y_] := thing[x y]; (* Example invalid operation: *) thing /: Power[_thing, _] := $Failed; (* Format value: *) thing /: Format[thing, StandardForm] = Interpretation[ToExpression["example`thing"], thing]; (* Return symbol: *) thing[contents] ]; End[]; EndPackage[]; 

Now we can write, e.g,

myThing = new@thing[73]; 4 myThing + 3 

which gives:

thing[295] (* == thing[4 * 73 + 3] *) 

However, despite the display form (which can also be copied and pasted thanks to Interpretation), the internal representation is quite different:

% // InputForm (* -> thing$576[295] *) 

As a result we can't just conjur things up without invoking new, as the methods defined on real things simply won't exist in that case:

myNewThing = thing[48]; myNewThing + 17 (* 17 + thing[48] *) 

Strictly speaking, the format value would have been enough to answer your question as stated. However, it seems like an object oriented approach is quite a natural fit for what you're probably trying to achieve here, so the extra effort may be worthwhile for maintainability and robustness reasons if you intend to have a lot of different objects each with their own private methods and/or internal state.