Sza*_*lcs 6 wolfram-mathematica reverse-engineering
偶尔我们会研究某些System`
函数是如何定义的(当它们用Mathematica编写时).这个问题是关于最好的方法.
要记住的要点:
病程中ReadProtected
需要先删除.
Builtins通常需要在加载到内核之前至少使用一次.当它们具有扩展功能(例如通过选项)时,单个简单调用通常是否足够?
Information
(??
)以难以阅读的格式给出定义(没有缩进,并且所有私有上下文名称都是前置的).什么是摆脱上下文名称,并获得格式化代码的最佳方法?
摆脱某些背景的一个想法是Block[{$ContextPath = Append[$ContextPath, "SomeContext`Private`"], Information[symbol]]
.代码可以使用Workbench自动格式化.一些问题仍然存在,例如Information
不引用字符串,从而阻止代码被复制到Workbench中.
一般来说,我对人们如何做到这一点感兴趣,他们使用什么方法使内置代码尽可能易于阅读.
使用案例:例如,最近我深入研究了RunThrough
当我发现它在Windows XP上无法运行时的代码(事实证明,当它们的路径包含空格时,它无法引用临时文件的名称).
更新: 似乎曾经有一个函数用于打印没有上下文的定义Developer`ContextFreeForm
,但它在新版本中不再起作用.
关于漂亮的打印:以下是一个非常原理的代码,它基于@ Mr.Wizard的答案,表明一些简单的规则可以大大提高代码的可读性:
Internal`InheritedBlock[{RunThrough},
Unprotect[RunThrough];
ClearAttributes[RunThrough, ReadProtected];
Block[{$ContextPath = Append[$ContextPath, "System`Dump`"]},
With[{boxes = ToBoxes@ DownValues[RunThrough]},
CellPrint[Cell[BoxData[#], "Input"]] &[
boxes /.
f_[left___, "\[RuleDelayed]", right___] :>
f[left, "\[RuleDelayed]", "\n", right] //.
{
RowBox[{left___, ";", next : Except["\n"], right___}] :>
RowBox[{left, ";", "\n", "\t", next, right}],
RowBox[{sc : ("Block" | "Module" | "With"), "[",
RowBox[{vars_, ",", body_}], "]"}] :>
RowBox[{sc, "[", RowBox[{vars, ",", "\n\t", body}], "]"}]
}]]]]
Run Code Online (Sandbox Code Playgroud)
这肯定不是一般的解决方案(特别是在没有很多单独的语句的情况下它不能很好地嵌套深层嵌套的功能代码),但我相信它可以在没有太多麻烦的情况下进行改进和推广,以涵盖许多感兴趣的案例.
好问题,因为我认为我还没有看到过这个问题.
我基本上和你概述的一样.您可以通过以下方式获得Definition
更多不同的打印输出和更多信息FullDefinition
:
Unprotect[RunThrough];
ClearAttributes[RunThrough, ReadProtected]
Block[{$ContextPath = Append[$ContextPath, "System`Dump`"]},
Print @ FullDefinition @ RunThrough
]
Run Code Online (Sandbox Code Playgroud)