簡體   English   中英

如何在 Elixir 中“檢查文件”(或字符串)?

[英]How to "inspect to file" (or to string) in Elixir?

在 Elixir 中,我們可以IO.inspect anyStructureanyStructure的內部結構打印到 output。是否有與 output 類似的方法將其打印到文件(或者,作為更靈活的解決方案,打印到字符串)?

我瀏覽了一些關於調試io的文章,但沒有看到解決方案。 我也試過

{:ok, file} = File.open("test.log", [:append, {:delayed_write, 100, 20}])
structure = %{ a: 1, b: 2 }
IO.binwrite(file, structure)
File.close file

但這導致

no function clause matching in IO.binwrite/2 [...]
def binwrite(device, iodata) when is_list(iodata) or is_binary(iodata)

我還用谷歌搜索了一些“長生不老葯序列化”和“長生不老葯 object 到字符串”,但沒有發現任何有用的東西(比如:erlang.term_to_binary返回,嗯,二進制)。 有沒有一種簡單的方法可以將IO.inspect打印到文件或字符串中的結果相同?

已經有inspect/2 function (與IO.inspect ),只有 go :

#> inspect({1,2,3})
"{1, 2, 3}"

#> h inspect/2
                         def inspect(term, opts \\ [])

  @spec inspect(
          Inspect.t(),
          keyword()
        ) :: String.t()

Inspects the given argument according to the Inspect protocol. The second
argument is a keyword list with options to control inspection.


之后你可以用字符串做任何你想做的事。

你可以給IO.inspect一個額外的參數來告訴它寫到哪里:

{:ok, pid} = StringIO.open("")
IO.inspect(pid, %{test: "data"}, label: "IO.inspect options work too \o/")
{:ok, {_in, out}} = StringIO.close(pid)

out # "IO.inspect options work too o/: %{test: \"data\"}\n"

它接受要寫入的進程的pid StringIO提供了這樣一個過程,在關閉時返回一個字符串。

在 Elixir 中,我們可以 IO.inspect anyStructure 將 anyStructure 的內部結構打印到 output。

這是不完全正確的。 IO.inspect使用檢查協議。 您看到的不是該結構的內部結構,而是該結構對 Inspect 協議的實現是為了生成而編寫的。 您可以為檢查提供不同的選項,這些選項在Inspect.Opts中定義,其中之一是structs: false ,它將結構打印為映射。

例如,檢查范圍結構:

iex> inspect(1..10)
"1..10"
iex> inspect(1..10, structs: false)
"%{__struct__: Range, first: 1, last: 10, step: 1}"

要回答您的問題並添加其他答案,這里有一個方法使用File.open!/3重用一個打開的文件並記錄對同一文件的多個檢查調用,然后關閉該文件:

File.open!("test.log", [:write], fn file ->
  IO.inspect(file, %{ a: 1, b: 2 }, [])
  IO.inspect(file, "logging a string", [])
  IO.inspect(file, DateTime.utc_now!(), [])
  IO.inspect(file, DateTime.utc_now!(), structs: false)
end)

這會產生以下test.log文件:

%{a: 1, b: 2}
"logging a string"
~U[2022-04-29 09:51:46.467338Z]
%{
  __struct__: DateTime,
  calendar: Calendar.ISO,
  day: 29,
  hour: 9,
  microsecond: {485474, 6},
  minute: 51,
  month: 4,
  second: 46,
  std_offset: 0,
  time_zone: "Etc/UTC",
  utc_offset: 0,
  year: 2022,
  zone_abbr: "UTC"
}

您只需要組合返回二進制文件的inspect/2File.write/3或任何其他 function 轉儲到文件。

File.write("test.log", inspect(%{a: 1, b: 2}, limit: :infinity))

請注意limit: :infinity選項,如果沒有它,長結構將被截斷,以便在檢查stdout時具有更好的可讀性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM