F#interactive - 如何查看当前会话中定义的所有变量

时间:2011-02-14 20:43:16

标签: f# f#-interactive

在F#interactive中,如何查看此会话中定义的变量/函数列表?就像python中的函数whos()或R中的ls()一样?感谢。

3 个答案:

答案 0 :(得分:16)

您可以使用.NET Reflection实现此功能 - 局部变量和函数在单个动态程序集中定义为类型的静态属性/方法。您可以通过调用GetExecutingAssembly(在FSI本身中)获取该程序集,然后浏览类型以查找所有合适的属性。

以下是获取局部变量的合理工作函数:

open System.Reflection
open System.Collections.Generic

let getVariables() = 
  let types = Assembly.GetExecutingAssembly().GetTypes()
  [ for t in types |> Seq.sortBy (fun t -> t.Name) do
      if t.Name.StartsWith("FSI_") then 
        let flags = BindingFlags.Static ||| BindingFlags.NonPublic |||
                    BindingFlags.Public
        for m in t.GetProperties(flags) do 
          yield m.Name, lazy m.GetValue(null, [||]) ] |> dict

以下是一个例子:

> let test1 = "Hello world";;
val test1 : string = "Hello world"

> let test2 = 42;;
val test2 : int = 42

> let vars = getVariables();;
val vars : System.Collections.Generic.IDictionary<string,Lazy<obj>>

> vars.["test1"].Value;;
val it : obj = "Hello world"

> vars.["test2"].Value;;
val it : obj = 42

该函数返回“lazy”值(因为这是编写它的最简单的方法,而不事先读取所有变量的值,这将很慢),所以你需要使用{{ 1}}属性。还要注意你得到Value - 因为F#类型系统无法知道类型 - 你必须动态地使用它。您可以通过迭代object ...

来获取所有名称

答案 1 :(得分:7)

我正在开发FsEye,它使用@Tomas'技术的修改版本(过滤掉单位和函数值变量的vars,只采用最新的it var)来获取所有FSI会话变量每次提交并在树中以可视方式显示它们,以便您可以深入查看它们的对象图。

您可以看到我修改后的版本here

答案 2 :(得分:1)

不幸的是,现阶段没有办法在FSI中这样做。

相关问题