私は、フォームの多くのコードを書くことにしそうだするプロジェクトに取り組んでいます:エリクサーマクロ、引用ビット列patternmatchタイプ
defmodule Kind
defstruct [name1, name2, name3]
@type t :: %Kind{name1: integer(), name2: integer(), name3: binary()}
def unpack(input) do
with <<name1::integer-8>> <- Enum.take(input, 1),
<<name2::integer-little-32>> <- Enum.take(input, 4),
<<name3::binary-10>> <- Enum.take(input, 10),
do: %Kind{name1: name1, name2: name2, name3: name3>>
end
end
(、input
を入力名とタイプの任意のセットについて
これはマクロで処理できるので、(例えば)use Unpack quote([{name1, integer-8}, {name2, integer-little-32}, {name3, binary-10}])
と書くだけで、必要な構造体typedefを自動的に生成できるので、非常に便利です。固定サイズの任意の名前のついたフィールドに対して、アンパック機能を使用します。それを拡張して、タプルに3番目のフィールドを追加して、可変サイズの型を処理する関数を渡すこともできました。私はそれの簡単なバージョンを実行しようとする場合残念ながら、(一つだけのサイズのフィールドを取り、それだけに1をマッチング):
defmodule Unpack do
defmacro testmacro({name, kind}) do
quote do
<<unquote(name)::unqote(kind)>> = 1
end
end
end
システムは、それがquote/1
に無効な引数を持っていると言われます。これは、ビットストリングパターンマッチングで使用される "タイプ"が一般的なビットストリングリテラルと同様に特別な形式であり、それらの特定のアイテムが他の場所では使用されないためと考えています。
どうすれば回避できますか?私は5つから20つの異なるフィールドのそれぞれを解凍するパックされた構造体のダース以上の種類があります。もし私がこれをしなければ、おそらく私の手を救うためにおそらくVimマクロに頼るでしょう...しかし、これは、維持するために大量の非常に反復的なコードを持つことを本当に助けません。
は、あなたがそのエラーを与える完全なコードを投稿することができますか? 2番目のスニペットは、typo(unqote)を修正し、RHSでバイナリを使用すると(そのパターンを整数にマッチさせることはできません)、私のために働きます。 – Dogbert
...いいえ、そのコードは私がテストしたiexセッションから直接コピーされました。どうやら、私は誤字が見つかりませんでした。まあ、それはむしろ恥ずかしいです。削除する。 –
@Dogbert問題が小さくても、あなたはまだそれに答えています。先に進んで、それを回答として入れて、私は承認します。 –