⌈Interfaces⌋
⌈ The idea for this package is that it will be used inside other packages to provide an easy, standard way to get all the nice OOP-like boilerplate in place that one generally would for an object based on an Association⌋
BeginPackage["InterfaceObjects`"];
RegisterInterface::usage= "Registers an object interface";
$InterfacePropertyStore::usage= "ExpressionStore for cached object properties";InterfaceSetProperty::usage= "Sets a property value";InterfacePropertyValue::usage= "Gets a property value"; InterfaceRemoveProperty::usage= "Removes a property value";InterfacePropertyList::usage= "Lists the properties on an object";InterfaceCopyProperties::usage= "Copies properties from one object to another";
InterfaceMethod::usage= "Alias for defining object methods";InterfaceAttribute::usage= "Alias for defining object attributes";InterfaceOverride::usage= "Alias for defining object UpValues";
InterfaceModify::usage= "Replace keys in one interface with new values";InterfaceAssociation::usage= "Extracts the underlying Association from an interface";
Begin["`Private`"];
⌈Properties⌋
If!ValueQ@$InterfacePropertyStore, $InterfacePropertyStore=Language`NewExpressionStore["<ObjectPropertyStore>"] ;
⌈get⌋
⌈set⌋
⌈set⌋
⌈remove⌋
⌈keys⌋
⌈computeProp⌋
⌈copyProps⌋
⌈Properties⌋
⌈CopyProperties⌋
⌈RegisterInterface⌋
⌈ This function makes it really easy to create a new object and avoid the boilerplate⌋
⌈Defaults⌋
⌈RegisterInterface⌋
⌈$InterfaceData⌋
⌈iRegisterInterfaceEntryQ⌋
⌈iRegisterInterfaceValidator⌋
⌈iRegisterInterfaceConstructor⌋
⌈iRegisterInterfaceMutationHandler⌋
⌈iRegisterInterfaceMutationHandler⌋
⌈iRegisterInterfaceMethod⌋
iRegisterInterfaceMethod~SetAttributes~HoldRest;iRegisterInterfaceMethod head_, methodName_, lhs_, args___, def_ := With mn=methodName, valid=InterfaceValidator[head], meths=InterfaceMethods[head], attrs=Attributes[head] , If[MemberQ[attrs,Protected],Unprotect[head]]; InterfaceMethods[head]= Ifmeths===Null, <|mnTrue|>, Append[meths,mnTrue] ; head/:lhs?valid[mn[args]]:= def; head/:lhs?valid[mn][args]:= def; If[MemberQ[attrs,Protected],Protect[head]]; ;
Unprotect[InterfaceMethod];InterfaceMethod/: InterfaceMethod[head_] lhs_[method_][args___] :=def_ := iRegisterInterfaceMethod[head,method,lhs,args,def];InterfaceMethod/: InterfaceMethod[head_] lhs_[method_[[args___]]] :=def_ := iRegisterInterfaceMethod[head,method,lhs,args,def];Protect[InterfaceMethod];
⌈iRegisterInterfaceAttribute⌋
⌈iRegisterInterfaceOverride⌋
⌈iRegisterInterfaceAccessor⌋
iRegisterInterfaceAccessor[head_,dispatcher_]:= With ea=If[!AssociationQ@dispatcher,<|"Keys"dispatcher|>,dispatcher], valid=InterfaceValidator[head] , IfKeyExistsQ[ea,"Keys"], With{lookup=dispatcher["Keys"]}, obj_head?validattr_String? !KeyExistsQ Join[InterfaceMethods[head],InterfaceAttributes[head]], # &:= With[{res=lookup[obj,attr]},res/;Head[res]=!=lookup]; obj_head?valid[attr:Except[_String|_String[___]]]:= With[{res=lookup[obj,attr]},res/;Head[res]=!=lookup]; obj_head?valid[attr1_,attrs__]:= With[{res=lookup[obj,attr1,attrs]},res/;Head[res]=!=lookup]; ; ; IfKeyExistsQ[ea,"Parts"], With{part=dispatcher["Parts"]}, head/:obj_head?valid[[p__]]:= With{res=part[obj,p]}, res/;Head[res]=!=part ; ; ; ;
⌈Modifications⌋