[Elixir]パターンマッチを使って条件分岐を関数で分ける

Elixirは関数定義の引数に対してパターンマッチを利用できます。 ちょっと、ちゃんとElixirっぽくしようということで使ってみました。 対象は以下。 https://github.com/KazuCocoa/simple_app_reporter_ex/blob/master/lib/reporter.ex get_body_json という関数は、HTTPoisonのレスポンスを引数として、そのレスポンスに適した処理を行うというものです。 修正前 caseを使って、得られたHTTPoisonのレスポンス毎に処理を分けています。 1つの関数内で条件が分岐するので、関数内の処理が必然的に多くなります。 修正後 関数定義の引数でパターンマッチを利用しています。上記の case における条件がそのまま関数定義になります。 この結果、 get_body_json() という関数に値を与えると、引数のHTTPoisonの状態によってElixirが勝手に処理を分けます。 1つの関数が過度に肥大化しなくなり、関数が最低限の責務を持つようにプログラムできるのが良いですね 🙂 締め Elixirは、条件分岐を処理する方法として 関数定義 case if cond がありますが、個人的には上記の順で考える頭を作っていきたいなと思ってます。 テストシナリオを書くときも結構条件分岐は出てくるのですが、こういう感じで責務を分けることができると処理を集中できて良いなーとふと。More

ElixirのバージョンコントロールをKiexで行う

Elixirも1.0.5がリリースされたことで、 rbenv のようなバージョンコントロールないかなーと探してみたら、kiexがありました。 https://github.com/taylor/kiex 使い方は簡単。 以下コマンドを実行する bash_profileなどに以下を追記する。 kiex コマンドを実施する この時点では、1.0.5が最新なので、 $ kiex install 1.0.5を実施しました。 あとは、 use や default で指定してあげれば良いですね。 ~/.kiex/ 配下に、gitやビルドした結果が格納されて、 use などのコマンドで切り替えて複数バージョンを使い分ける、ということになります。 なるほど。More

アプリのレビューを新着順で取得するライブラリをElixirで実装してみた

過去、 GooglePlay/AppStoreのレビューを取得するスクリプトを少し整えた のようにRubyでAppStoreやGooglePlayで新着レビューを取得する実装を書きました。 それを題材にElixirを使って同様のライブラリを書いてみました。Elixir歴は、Getting Startedを1巡したくらい。 GitHub https://github.com/KazuCocoa/simple_app_reporter_ex Hex https://hex.pm/packages/reporter Doc http://hexdocs.pm/reporter/0.1.1/ HTTPoison、Poison、Quinn、Flokiを使って、HTTP通信やJSON、XML、HTMLスクレイピングを満遍なく触った気がします。 テストデータ用意してのDocTestや、ExUnitなどもザーッと触りましたが、Elixirというか、Erlangの良さであるprocessを使った並行実行は実装していません。 もう少し気が向けば触っていこうかなと思っている次第。More

Learning META-PROGRAMMING IN ELIXIR

Macroに関して学んだ。 quote で与えた文字列を Abstract Syntax Tree (AST) としてタプルで得ることができる。 unquote は、quoteで囲まれた中で使うことでquoteの中でunquoteした要素をinjectすることができる。 quoteやunquoteなどはこちらで確認可能。 他にもこちらとか。 defmoduleの中で @before_compile TestCase のように記述することで、コンパイル時にTestCase.__before_compile__/1を実施することができます。このようなModuleに対する定義は以下を参照すると良いとか。 http://elixir-lang.org/docs/stable/elixir/#!Module.html Getting Startedをすべて終えた… Macroなんかはまだ馴染まないとなーという感じですが、単純なコードは読み書きできてきた感じ。 ちょっとやりたいことがあるので、Phoenixのtutorialを読んでいこうかな。More

GimeiのElixir版を練習がてら書いてたらちゃんとしたものが公開された

まだElixirのチュートリアルをちゃんとやり始めて1週間くらいなのですが、ここ最近、Elixirを学んでみています。チュートリアルも終わり何か書きたいな、と思った時、Gimeiが他言語でポートされているブーム?みたくなっているぽいことを知りました。 ひとまず練習がてら同じようなものを実装しながら学ぼうと思い、以下のような練習リポジトリを作り、少しづつ手を動かし始めました。Hexで公開してからリポジトリを公開しようかなと思ってたのですが、作っている途中にちゃんと経験されている方が書いたgimeiのElixir版が出ていたのを昨日見つけたので、まだ全然途中で中途半端な感じなのですがprivateからpublicにしていいかなーというくらいのノリでリポジトリをpublicにしました。 もしElixirに興味のある方は、後者のgimei_exを使いましょう。 私のやつ https://github.com/KazuCocoa/elixir-gimei ちゃんとしている方 https://github.com/ma2gedev/gimei_ex 私のリポジトリは機能的にもまだ未完全です。また、DocTestを使ってみたりと違ったこともしています。これからも多分色々TODO増減しながら試していきそうです。Hexにあげるまではしてみたいな。 Erlangのライブラリ探して使ったり、関数型のような記述をしたり。まだ手続き型の考えのほうが強いですが、caseやrecursiveな書き方は、Elixirは好きな感じです。Elixir学んでいるとErlangも学ぶこともできるという特典付き。 ともあれ、こういう新しいものを学んで世界を広げるって、良いですね。More

MIX AND OTP vol 2

Mix and OTPの後半。 ETS ここは、GenServer、Supervisor付近の説明から。 リンク http://elixir-lang.org/docs/stable/elixir/#!GenServer.html http://elixir-lang.org/docs/stable/elixir/#!Supervisor.html ソースコードは以下 https://github.com/elixir-lang/elixir/blob/v1.0.4/lib/elixir/lib/supervisor.ex processによる状態の保持と、etsによる保持はいくつか違うところがあります。 processに状態を保持する場合、そのprocessが死んだらそれに保存されるデータも無くなります。一方、etsは複数のprocessに共有されるキャッシュのように扱うことができます。 共有キャッシュのように扱うことができるので、etsに対しては書き込み制限をしたりします。また、callbackに関しても同期的に行う必要がるなどの制約がでてきます。 ここら辺の説明がされますが、etsを生成したprocessが死んだ場合、etsも合わせて自動的に閉じられます。これは、etsはそれを起動したprocessにリンクされているから。 ということは、supervisorで起動させて、publicにするとprocessに依存して、それが死ぬとetsが閉じられるという事態も回避できそうです。 このページの最後の箇所の、 :ets.foldl() のfnへの引数で、 {name, pid} が与えられているのですがこれがどこから来たのかよくわからなかった… のですが、 の所を見て納得。 :ets(table) に保存していた値がfnの引数として与えられ、それに対して関数が適用されて出力が得られるというものなのですね。説明にもさらりと描かれているのですが、initの中に突然nameとpidが出てきたので???になりました。 このfoldlのErlangによるspecは以下。 pipelineでメソッドチェインぽく描くとき、 () はsつけるべきなのですね。そのほうが意図が伝わるコードになりますし。引数の数が違う同名の関数もあるので、これはすごく納得。 なるほどなるほど。 Task and gen-tcp Taskは、非同期に処理を行うprocess。 processなので、そのprocessを監視するためにsupervisorへの登録が大事になってくるのですが、そこの詳しくはTask.Supervisorをみると良さそう。 こうざっと読んでみると、Supervisorが非常に重要な位置をしめて、そのsupervisorが監視する子プロセスへの再起動strategyも大事。これらがErlangというかElixirの安定性を支えているのですね。 結構、Unit testでロジックをしっかりかかないと、ここはdebugとかスキル必要そうだ。。。 Docs, tests and pipelines ExUnit.DocTest、半端ない。ドキュメントがそのままiexのコマンドベースでのテストコードに置き換わるのですね。 http://elixir-lang.org/docs/stable/ex_unit/#!ExUnit.DocTest.html 例えば、以下の@docで囲んだドキュメントになる範囲の iex> とその次の行がコマンドと期待結果になって、テストが実施される。APIとして目に見えるインタフェースでは、このテストかなり役立つのでは。autodocみたいなものですね。 ここは、最後はどのようなテストコードを作っていくか、というのも含め、戦略はチームで形作っていく必要あるよね、ってもので終わってました。 Distributed tasks and configuration 最後は、異なるノード間での通信が話題です。ネットワーク越しに異なるノード間で通信をやりとりし、一方から送った処理をもう一方のノードで実行するということが可能です。 Node.spawn_link/2 を使うのですが、普通に使うとsupervisorの管理下に置くことができないので、以下の3通りが紹介されています。…More

MIX AND OTP vol 1

ElixirのGetting startedも、Mix and OTPの話に入りました。 http://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html でつくられる各ファイルの説明などから始まり、実際にExUnitでテストを書くまでの説明が載っています。 Agent Elixirはimmutable languageなので、状態を保持するにはProcessesかETS(Erlang Term Storage)を使う必要があります。ここは、Getting StartのところのProcessやTaskのところで説明があった、TaskとかAgentの話ですね。 ExUnit setup が用意されているのだけれど、このsetupのcallbackが後の test へ渡されるらしい。なので、setupで最後に渡す引数を渡して、それを test で受け取らないといけないのですね。 setupやsetup_allがあれば、teardownに該当するものもあるのかな?と思ってみると、 on_exit があるのですね。 ExUnit.Callbacksの中に、以下のような定義がありました。 これは ExUnit.OnExitHandler をcaseで呼んで使っている模様。 また、このon_exit自体はaddされるだけなので、ExUnit.OnExitHandlerのもとがどこにあるかコードで追ってみると、最終的には ExUnit.Runner の run の中にある loop に行き着いた。この処理開始のときに、 ExUnit.OnExitHandler も登録されて処理が進み、 on_exit でOnExithandlerにfnを登録、テストケースが終わった時点で実行する、と。なるほど。 もう少し、ExUnitを遡ると、ExUnit のモジュールでstart/1が定義されていて、その中の System.at_exit にテストケースが登録されていることが一番の始まりみたい。 ちなみに、この at_exit の説明は以下。 Registers a program exit handler function. Registers a function that will…More

Get start Elixir vol 3

Sigils Elixirでは、正規表現を書くときに ~r/neko/ と書きます。その ~r の書き方箇所のバリエーションや、 ~w 、 ~W などのword list、カスタムsigilsの作り方が書いていました。Rubyでも%wといったものをよく使うので、こちらも使いそうですね。 try, catch and rescueの使い方 In Elixir, we avoid using try/rescue because we don’t use errors for control flow. We take errors literally: they are reserved to unexpected and/or exceptional situations. In case you actually need flow control constructs, throws should be used. That’s what…More

Get start Elixir vol 2

processのところから、protocolのところまで。 processの話の中で、以下の文言がありました。 Process and links play an important role when building fault-tolerant systems. In Elixir applications, we often link our processes to supervisors which will detect when a process dies and start a new process in its place. This is only possible because processes are isolated and don’t share anything by default. And if processes…More

再帰的な書き方に頭が馴染んできた: Elixir

exercismでElixirの問題を解いていた時、いろいろなるほどなーと面白かったのでメモ。 仕様は、入力(sentence)に対して単語区切りごとに、sentence全体の文字をキーに含まれる文字をカウントする、というもの。 例えば、 “abc de fge” を入力とすると、abc、de、fgeがそれぞれ1つづつ存在するとカウントする。 “abc de abc” を入力とすると、abcが2つ、deが1つ存在するとカウントする、というもの。 Elixirだと、繰り返しは再帰的に書く。数列的な書き方になるので、少し頭になじませる時間が必要でしたが、再帰的な書き方に考えが馴染むと数学のようにかけて、個人的には書きやすかったです。プログラムだと手続き型に慣れていたけれど、関数的にかけると数学的な考え方をそのまま残せるのが良いですね。 これを、さらにreduceを使って書いてみます。 Elixir1.0.4におけるreduceの説明は以下。 Elixir、なるほどね。More