代码之家  ›  专栏  ›  技术社区  ›  John Smith

反向移植sigils并使其与变量一起工作

  •  0
  • John Smith  · 技术社区  · 5 年前

    所以我刚开始喝灵丹妙药,看到了电流 master 添加对 ~U[2015-01-13 13:00:07Z] 创建/分析UTC日期的sigil。

    代码如下:

    defmodule MySigils do
      defmacro sigil_U(datetime_string, modifiers)
    
      defmacro sigil_U({:<<>>, _, [string]}, []) do
        Macro.escape(datetime_from_utc_iso8601!(string))
      end
    
      defp datetime_from_utc_iso8601!(string) do
        case DateTime.from_iso8601(string) do
          {:ok, utc_datetime, 0} ->
            utc_datetime
    
          {:ok, _datetime, _offset} ->
            raise ArgumentError,
                  "cannot parse #{inspect(string)} as UTC datetime, reason: :non_utc_offset"
    
          {:error, reason} ->
            raise ArgumentError,
                  "cannot parse #{inspect(string)} as UTC datetime, reason: #{inspect(reason)}"
        end
      end
    end
    

    在我的代码中,我试图用一个变量 timestamp

    timestamp = Map.get(item, "timestamp")
    ~U[timestamp]
    ** (ArgumentError) cannot parse "timestamp" as UTC datetime, reason: :invalid_format
    

    但是 时间戳 正在被解释为“是”,而不是上一个匹配项。

    我有办法让它工作吗?我需要引用/取消引用某些内容吗?除了使用 DateTime.from_iso8601/1 直接。

    0 回复  |  直到 5 年前
        1
  •  1
  •   fhdhsni    5 年前

    sigil分隔符之间的所有内容都作为字符串发送。所以 timestamp 变量被发送到 sigil_U 作为字符串 "timestamp" 是的。有些sigil允许使用小写字母进行插值。例如 ~r 对战 ~R 以下内容:

    iex(1)> x = "foo"
    "foo"
    
    iex(2)> ~R/#{x}/
    ~r/\#{x}/
    
    iex(3)> ~r/#{x}/
    ~r/foo/
    

    但在这种情况下没有小写版本的 西格尔 定义为无法插入 时间戳 是的。

    推荐文章