Information / Information`InformationValueForm usando Full- o InputForm
Tengo un problema con la Informationfunción incorporada para símbolos definidos por el usuario con StandardForm personalizado en Mathematica 12.1.1.0:
Por ejemplo con las definiciones de funciones
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := Row[{a, b}, " "]
CM::usage = "CM";
la consulta Information[CM]da como resultado:
Las definiciones en la salida se formatean usando StandardForm sin siquiera mostrarlo correctamente. El mismo problema ocurre cuando se define UpValues . En este punto, esto hace que el cuadro Información sea ilegible, pero empeora cuando se usa InterpretationBox. Con
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := With[{box = ToBoxes[Row[{a, b}," "]]},
RawBoxes[InterpretationBox[RowBox[{box}], CM[a, b]]]
];
CM::usage = "CM";
Una llamada a Information[CM]da como resultado una recursividad infinita y varias advertencias y errores:
Inspección FullFormde los resultados de Information[CM]revela
InformationData[Association[
...
Rule["DownValues",Information`InformationValueForm[DownValues,CM,List[RuleDelayed[CM[1,Pattern[a,BlankSequence[]]],CM[a]]]]],
...
Rule["FormatValues",Information`InformationValueForm[FormatValues,CM,List[RuleDelayed[MakeBoxes[CM[Pattern[a,Blank[]],Pattern[b,BlankNullSequence[]]],StandardForm],Format[With[List[Set[box,ToBoxes[Row[List[a,b]," "]]]],RawBoxes[InterpretationBox[RowBox[List[box]],CM[a,b]]]],StandardForm]]]]],
...
]]
y con ella la función interna y, por supuesto, no documentada ...InformationValueFormque se utiliza para generar las definiciones encontradas.
¿Hay alguna forma de configurar o manipular Informationo el subyacente InformationValueFormpara mostrar las definiciones de función usando Full- o InputForm ? Pude manipular la salida de FullForm convirtiendo los argumentos de RuleDelayedinside InformationValueForma Strings, pero no pude adjuntar esta corrección a Informationo InformationValueForm.
No entiendo la decisión de diseño detrás del uso de StandardForm en la salida de Informationfunciones definidas por el usuario y, en mi opinión, toda la situación es básicamente un error. El problema real son las infinitas recursiones y errores para funciones de formato más complicadas que pueden bloquear el kernel y / o el front-end. Tiendo a documentar mis funciones y a veces me gusta usar Informationpara recordarme el orden de los argumentos. La solución alternativa bastante insatisfactoria que estoy usando actualmente es deshabilitar Informationmis funciones formateadas usando UpValues:
CM /: Information[CM, opts___] := CM::usage;
De esta manera, al menos tengo acceso al mensaje de uso, pero las definiciones, opciones y todos los demás datos Informationno son accesibles usando esta solución.
Respuestas
Encontré la respuesta a mi pregunta en el código fuente de varias funciones básicas de Mathematica. El uso de la función inmensamente útil GeneralUtilities`PrintDefinitionsen eg InterpolatingFunction(o cualquier otra función central que se use BoxForm` ArrangeSummaryBoxpara su salida formateada) revela la función / variable del kernel protegida BoxForm`UseIcons. Esto parece ser una variable dinámica relacionada con lo BoxFormque es falso para las cajas generadas por Information. El siguiente código permite el formato personalizado en el cuaderno, pero no en la salida de Information(incluido ?y ??) y otros entornos con BoxForm`UseIcons=False:
MakeBoxes[..., StandartForm] /; BoxForm`UseIcons := ...
Adjuntar el formato personalizado a en MakeBoxeslugar de Formaty verificar la variable BoxForm`UseIconshace el truco y responde mi pregunta a mi satisfacción. Esta solución es, con mucho, la mejor solución en comparación con mi respuesta anterior y el método de elección para al menos algunas funciones básicas con una salida con formato elegante. Publiqué esta nueva respuesta ya que la estrategia de solución difiere de la anterior.
Es una lástima que esto no está documentado junto Formato MakeBoxesni siquiera una opción o por defecto de esas funciones.
Encontré una solución algo factible basada en UpValues en los métodos / símbolos de usuario problemáticos, por ejemplo:
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b__], StandardForm] := Row[{a, b}, " "]
CM /: Format[CM[a_], StandardForm] := a
Unprotect[CMinfo]; ClearAll[CMinfo];
CMinfo /: Format[CMinfo, StandardForm] = "CM";
Attributes[CMinfo] = {Protected, Constant};
CM /: Information`InformationValueForm[val_, CM, exp_List] :=
With[{s = ReleaseHold[Hold[exp] /. CM -> CMinfo]},
Information`InformationValueForm[val, CMinfo, s]]
CM /: Information`InformationValueForm[FormatValues, CM, exp_List] :=
With[{s = {Skeleton[Length[exp]]}},
Information`InformationValueForm[val, CMinfo, s]]
CM::usage = "CM::usage";
que da como resultado la salida
El símbolo CMinfose usa en ...InformationValueForm[...]lugar de CMpara evitar el formato en las definiciones. La salida para FormatValuestodavía está formateada y, por lo tanto, no es muy informativa, así que inserté un marcador de posición en su lugar. Tal vez con un poco más de trabajo también se podría hacer FormatValuesfuncionar.
Este enfoque funciona bastante bien para mí, pero todavía estoy bastante descontento con la necesidad de tales medidas. El Information[...]método debería funcionar desde el primer momento en funciones de usuario válidas. Así que todavía estoy a favor de llamar a todo el lío un error, pero gracias a @Michael E2 por señalar en los comentarios bajo la pregunta que la etiqueta 'error' requiere revisión. No leí la descripción de la etiqueta y la usé mal, lo siento.
Tenga en cuenta que ambos Information[CM]y ??CMfuncionan según lo previsto al modificar ...InformationValueForm[...], lo que sorprendentemente no es el caso de la solución presentada en mi pregunta (configuración CM /: Information[CM] := CM::usage).
Las formas de entrada especiales ?y ??no solo son especiales por su nombre, sino también especiales porque eluden UpValues por lo Informationque nuevamente me suena muy poco razonable.