2016-11-13 9 views
0

私の関数が頭の中でパターンマッチングを直接行うことを考えれば、関数がそれを呼び出すことなく与えられた入力に対してパターンが一致するかどうかをチェックする方法はありますか?キンダーのようなmatch?が機能します。私はwhenを気にせず、タプル内の原子や原子とのみ一致しています。ファンクションヘッドに一致するパターンがあるかどうかを確認しますか?

def init(:ok) do 
    ... 
end 

check(&init/1, :ok) # return true 
check(&init/1, :other) # return false 

私は、GenServerの状態を変更する入力のいくつかを扱う関数のリストを使用して、他の人を無視しています。各関数はタプルをとり、ある状態を取り、関数の頭が一致すると変更された状態を返し、そうでない場合は状態を返します。私は今この試みのためにtry/rescueラッパー関数を持っていますが、それはあまり美味しくありません。入力は可変長タプルであり、第1の要素は原子識別子である。

+0

これで何を達成しようとしていますか?もう少し文脈があれば、私たちはあなたの問題をより簡単に解決するかもしれません。 –

+0

@PatrickOscityが更新されました。それがまだ不明な場合はお気軽にお問い合わせください。 –

+0

@FilipHaglund関数を実行せずに関数の頭が一致するかどうかを確認することはできませんが、既存のツールで同じ目標を達成するにはいくつかの方法があると思います。もっとコードを表示できますか?私はあなたがしようとしていることを得るのに苦労している:| – whatyouhide

答えて

0

厳密に言えば、不可能です。 Elixir.FunctionClauseErrorは、基本的にはerlang function_clauseruntime errorのラッパーです。

オンザフライでチェックが行われますが、特定の句がチェックされている可能性がありますが、チェックする句のリストはありません。良い例は、あなたの前に座っている貪欲な猫でしょう。あなたはリンゴ、人参、またはクリップを食べようとするかもしれませんが、試していなければ、食べるかどうかは言えません。

一方、常にModule.__info__ :functionsについて問い合わせるオプションがあります。それはアリティで応答するので、すべてElixir.UndefinedFunctionErrorを検出して拒否することがあります。

実行時に句節が一致するため、許可された句のリストを受け取る方法がありません。この条項は、ガード(when)、明示的なパラメータ(:ok)の面倒な絡み、重複する可能性があると考えてください。それが述べたように


質問、:

check(&init/1, :ok) # return true 
check(&init/1, :other) # return false 

は、しかし、ブルートフォースソリューションを持っています。私はそれをお勧めしませんが、まだ利用可能です:としてcheckを実装し、Elixir.FunctionClauseErrorから関数と救助を呼び出します。

また、私はこの提案を持っていた男だった、共有しないでください。

+0

あなたのブルートフォースの解決策は、私が現在使っている解決策ですが、一般的には不可能であると私は同意しません。関数節の最初の引数を抽出し、それに 'match?'または大文字小文字を使用するマクロを書くことができます。私はちょっと魔法の少ないもっと慣れ親しんだ解決策を求めています。ここに問題はありません。 –

+0

"複雑なガードを持たない限り、関数節に最初の引数を抽出するマクロを書くことができます" - のみ。これは、どの句のマッチングが非常に限定されていて、人為的な例であり、この実装は正当なElixir節では失敗します。私の要点は「一般的には不可能なので、標準的なエリクシール関数では達成できないのです」 – mudasobwa

+0

しかし、私はそのような厳しい制約はありません。 –

関連する問題