Elixirにおけるメタプログラミングの落とし穴
この4つのパートシリーズの最後の部分に戻ってくださいmetaprogramming in Elixir .
以前に,マクロの様々な応用を調べた.
この部分では、エリクサーでメタプログラミングするときに遭遇する可能性があります一般的な落とし穴を掘ります.
マクロの一般的な危険
によるとofficial documentation :
すべてのためにmetaprogrammingを使用することを誘惑するかもしれない間、それは常に最高のオプションであるかもしれません.
The Applications of Macros このシリーズの一部は、マクロの使用例の大部分を概説します.
ただし、注意してマクロを使用する必要があります.
マクロを使うのを避けるために、これら三つの一般的な落とし穴を見ています. 不要な関数の注入 過剰注射行動 正規関数の置換 マクロを持つモジュールに不要な関数を注入した場合、何が起こるかを見て起動しましょう.
注:これらのポイントはMetaprogramming Elixir .
1 .マクロで不要な関数を注入する
マクロは呼び出し元に関数を注入するために使用することができますが、これは不要です.
例を見てみましょう.
ただし、
コードはその意味の意味を失い、初めての読者の理解を深める.
コードの意味的な意味を保持するには
注入行動上のマクロ
Elixirが呼び出しサイトにマクロを注入すると、動作はオーバーインジェクションできます.
の例に戻りましょう
どのような場合は、構文解析ロジック
テストによって
複数の継承子が存在するとき
これは、任意の継承者固有の動作が
そうすることができないならば、テスト範囲を下げることができます.
曖昧エラー報告
によって発生したランタイムエラー
そのため、
の最初の実装
これにより、上記の2つの問題が解決されます. コアの動作をテストするとき
構文解析のエラーは
注意:
オーバーインジェクション動作の例ではラッパーを使用していますが、通常のマクロにも同様に適用できます.
親指のルールはマクロの動作量を最小にすることです.
マクロを必要とする必要な情報/計算がいったんアクセス/実行されると、残りの動作をマクロから動かす必要があります.
我々が調べる最終的な落とし穴は、規則的な機能が十分であるとき、マクロの使用です.
通常の関数の代わりに使用されるマクロ
として、彼らは常にマクロを必要としない.場合によっては、マクロの動作を通常の関数で置き換えることができます.
例えば、コンパイル時の情報を必要としない動作(またはマクロを計算するマクロ)がマクロに置かれているとしましょう.
その動作はコンパイル時情報や計算のためのマクロを必要としません.注入される
Elixirにおけるメタプログラミング
我々は最終的にエリクサーのメタプロファイラにこの調査の終わりに来ている!
注意:偉大な力で大きな責任が来る.誤植Metaprogrammingはあなたを噛むために戻ることができますので、軽くトレッド.
このシリーズは、メタプログラミングとその複雑さを簡潔に説明することを目的としているが、それは、このトピックには、“聖書”という意味ではありません.
あなたがエリクサーでメタプログラミングについてもっと学ぶために使用できる多くの素晴らしいリソースがあります!ここでほんの数:
案内書
Understanding Elixir Macros - The Erlangelist * Official Elixir tutorial on metaprogramming Metaprogramming by Elixir School Metaprogramming in Elixir - Serokell 本
Metaprogramming Elixir * 協議
(*-非常に推奨)
読書のおかげで、次回あなたを参照してください!
P . S .あなたが彼らがプレスから降りるとすぐにエリキシル錬金術柱を読みたいならば.subscribe to our Elixir Alchemy newsletter and never miss a single post!
Jia Hao wooは、リトルレッドドットからの開発者です-シンガポール!彼は様々な技術をいじるのが大好きで、エリキシルを使っていて、およそ1年の間行きます.彼のプログラミング旅行に続いてくださいhis blog および.
以前に,マクロの様々な応用を調べた.
この部分では、エリクサーでメタプログラミングするときに遭遇する可能性があります一般的な落とし穴を掘ります.
マクロの一般的な危険
によるとofficial documentation :
Macros should only be used as a last resort. Remember that explicit is better than implicit. Clear code is better than
concise code.
すべてのためにmetaprogrammingを使用することを誘惑するかもしれない間、それは常に最高のオプションであるかもしれません.
The Applications of Macros このシリーズの一部は、マクロの使用例の大部分を概説します.
ただし、注意してマクロを使用する必要があります.
マクロを使うのを避けるために、これら三つの一般的な落とし穴を見ています.
注:これらのポイントはMetaprogramming Elixir .
1 .マクロで不要な関数を注入する
マクロは呼び出し元に関数を注入するために使用することができますが、これは不要です.
例を見てみましょう.
defmodule CalculatorTransformer do
defmacro __using__(_) do
quote do
def add(a, b), do: a + b
def subtract(a, b), do: a - b
def multiply(a, b), do: a * b
def divide(a, b), do: a / b
end
end
end
defmodule Hospital do
use CalculatorTransformer
def calculate_cost(suite, procedure) do
add(suite * 20, multiply(procedure, 5))
end
end
我々は様々な電卓機能を注入するHospital
モジュール識別子の必要性を排除する.ただし、
add
and multiply
今、彼らは薄い空気から表示されるようです.コードはその意味の意味を失い、初めての読者の理解を深める.
コードの意味的な意味を保持するには
CalculatorTransformer
通常のモジュールとして.このモジュールはimport
エドHospital
モジュール識別子を削除するには、次の手順に従いますdefmodule CalculatorTransformer do
def add(a, b), do: a + b
def subtract(a, b), do: a - b
def multiply(a, b), do: a * b
def divide(a, b), do: a / b
end
defmodule Hospital do
import CalculatorTransformer
def calculate_cost(suite, procedure) do
add(suite * 20, multiply(procedure, 5))
end
end
不要な機能を作成するのと同様に、マクロもモジュールへの動作を注入することができます.これがどういう意味か調べましょう.注入行動上のマクロ
Elixirが呼び出しサイトにマクロを注入すると、動作はオーバーインジェクションできます.
の例に戻りましょう
BaseWrapper
:どのような場合は、構文解析ロジック
post?
内部__using__
マクロ?defmacro __using__(opts) do
quote location: :keep, bind_quoted: [opts: opts] do
# ...
def post?(url, body) do
case post(url, body) do
{:ok, %HTTPoison.Response{status_code: code, body: body}} when code in 200..299 ->
{:ok, body}
{:ok, %HTTPoison.Response{body: body}} ->
IO.inspect(body)
error = body |> Map.get("error", body |> Map.get("errors", ""))
{:error, error}
{:error, %HTTPoison.Error{reason: reason}} ->
IO.inspect("reason #{reason}")
{:error, reason}
end
end
end
end
このアプローチには2つの問題があります.テストによって
post?
, あなたは、BaseWrapper
.複数の継承子が存在するとき
BaseWrapper
そして、post?
がInheritorに注入されると、すべての継承子を個別にテストする必要があります.これは、任意の継承者固有の動作が
post?
.そうすることができないならば、テスト範囲を下げることができます.
曖昧エラー報告
によって発生したランタイムエラー
post?
は継承者の下に記録されるBaseWrapper
.post?
することができます混乱を作成します.の最初の実装
BaseWrapper
代わりに、解析処理の大半をラッパーに移動します.この実装は、より意味があり、意味的に意味があり、読みやすい.これにより、上記の2つの問題が解決されます.
post?
, のみBaseWrapper.parse_post
がテストされている.構文解析のエラーは
BaseWrapper
.注意:
location: :keep
同様の方法で動作します.親指のルールはマクロの動作量を最小にすることです.
マクロを必要とする必要な情報/計算がいったんアクセス/実行されると、残りの動作をマクロから動かす必要があります.
我々が調べる最終的な落とし穴は、規則的な機能が十分であるとき、マクロの使用です.
通常の関数の代わりに使用されるマクロ
として、彼らは常にマクロを必要としない.場合によっては、マクロの動作を通常の関数で置き換えることができます.
例えば、コンパイル時の情報を必要としない動作(またはマクロを計算するマクロ)がマクロに置かれているとしましょう.
defmodule Foo do
defmacro double(x) do
quote do
doubled = unquote(x) * 2
doubled
end
end
end
defmodule Baz do
require Foo
def execute do
Foo.double(3)
end
end
iex(1)> Baz.execute
6
こちらです.double
簡単に正規の関数に置き換えることができました.その動作はコンパイル時情報や計算のためのマクロを必要としません.注入される
Baz
そしてexecute
は通常の関数と同じように呼び出されます.defmodule Foo do
def double(x), do: x * 2
end
defmodule Baz do
def execute, do: Foo.double(3)
end
iex(1)> Baz.execute
6
ご覧の通り、定義double
マクロとしては、通常の関数では何の利点もありません.Elixirにおけるメタプログラミング
我々は最終的にエリクサーのメタプロファイラにこの調査の終わりに来ている!
注意:偉大な力で大きな責任が来る.誤植Metaprogrammingはあなたを噛むために戻ることができますので、軽くトレッド.
このシリーズは、メタプログラミングとその複雑さを簡潔に説明することを目的としているが、それは、このトピックには、“聖書”という意味ではありません.
あなたがエリクサーでメタプログラミングについてもっと学ぶために使用できる多くの素晴らしいリソースがあります!ここでほんの数:
案内書
Understanding Elixir Macros - The Erlangelist *
Metaprogramming Elixir *
読書のおかげで、次回あなたを参照してください!
P . S .あなたが彼らがプレスから降りるとすぐにエリキシル錬金術柱を読みたいならば.subscribe to our Elixir Alchemy newsletter and never miss a single post!
Jia Hao wooは、リトルレッドドットからの開発者です-シンガポール!彼は様々な技術をいじるのが大好きで、エリキシルを使っていて、およそ1年の間行きます.彼のプログラミング旅行に続いてくださいhis blog および.
Reference
この問題について(Elixirにおけるメタプログラミングの落とし穴), 我々は、より多くの情報をここで見つけました https://dev.to/appsignal/pitfalls-of-metaprogramming-in-elixir-aj9テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol