[Erlang][Elixir]if condition in Erlang/Elixir

昨夜のElixirのifの使いかたに対しての話に参加して。メモ。 Elixirのifって、以下の通りcaseから構成されるmacroとしてKernelに定義されているのですよね。nilとfalseに一致したら else を行い、それ以外は if を行うと言う。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters # https://github.com/elixir-lang/elixir/blob/v1.2.5/lib/elixir/lib/kernel.ex#L2321 defmacro if(condition, clauses) do build_if(condition, clauses)…More

[Elixir]concurrent integration test with Hound and handle it with tag

雑にしか書きませんが、Phoenixのcontrollerのテストでは、あるURLへの操作に対する結果のチェックにはstatus codeが何か、そのtitle要素は何かといった簡単なHTML要素をみます。そこは静的な要素をチェックできるのですが、画面の遷移が絡んでくるとintegration testと呼ばれる段階のテストを用意する必要があります。 Elixirでは、その手のツールに以下の2つがあります。 Hound Wallaby Wallabyのほうが後発です。これはconcurrentなテストを主眼に開発されているようです。ただ、対応ブラウザがPhantomJSだけだったので、私はHoundを選びました。 そして、concurrent integration testを行うにはphoenix_ecto3.0 + Ecto 2.0を使う必要があります。これは、Ecto2.0から入ったownership制のsandbox環境を使い、concurrentなテストを実行する必要があるためです。 ※Ectoのこのownership制の話とか気になる人はこちらを読むと良いと思います。コード 設定 以下の設定説明を参考にすると、基本的なところは完了。サクッと実行できます。なのでここではリンクだけ… https://github.com/phoenixframework/phoenix_ecto#concurrent-acceptance-tests https://github.com/phoenixframework/phoenix_ecto#hound 私はfirefoxとWebDriverのstandaloneを使ってサクッと実行しました。 WebDriverはこちらからダウンドード可能です=> https://selenium-release.storage.googleapis.com/index.html tips 通常、この手のintegration testはブラウザを使うのでテスト実行が遅かったり不安定だったりします。そのため、その他のmodelやcontrollerのテストとは別に制御できるようにして、不要なときはskipするなりしたいです。 ここでは、tagを使って制御しましょう。ただ、よくあるメソッドごとに @tag をつけるのでは煩雑になるいっぽうなので、 integration_case.ex なんかを作って、それを読み込んだ全てのモジュールに対して勝手にtagがつくようなやり方です。 tagを付与する support/integration_case.ex にtagを設定する 以下のようにヘルパーを作ってあげると、 use MyApp.IntegrationCase したモジュールは自動的に @moduletag :integration のtagが付与されます。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than…More

[Elixir]Ecto.RepoのRepository Patternを見る

Mediumでたまたま Repository Pattern を見たこともあって、 Ecto.Repo を見てみました。こういうまとまっているフレームワーク見ると、手軽なデザインパターンの理解や頭の整理にもなりますよね。 Ecto.Query付近は随分前にざっと見ているので、今回は別。 [Elixir]EctoのQueryを少し読み解く ~ コードに前提条件が書かれるので読み解きやすいですね ~ Ecto 2.0から、 Ecto.Repo.first とかもdeprecatedになったので、その対応をついでにメモ。 以下の User は、 Ecto.scheme によって定義されたmodelです。それに対して、1件のemailに合致するデータを引っ張ってくるという処理です。 この Repo.first がdeprecatedなので、それをQueryを使って書き直すと以下のように書くことができます。 この時、 Ecto.Query.first の結果は以下のようになります。 ここは、実際にSQLを出す前のQueryを構築するところです。この Repo.one が実施されると、SQLが発行されてその結果がmodelの結果として得られます。以下は Repo.one まで行われた結果です。 Ecto.Query.first ではリクエストしたいSQLの構築、 Repo.one で実行と、クエリ構築とその実行が分離されていますね。 変更したdiffを合わせて置いておきます。 https://github.com/KazuCocoa/web_qa_vote/commit/4a0242455fb3b9c15d5c68d5e8e78336a2474b54More

[Elixir]マクロ defptとdefp、def

友人が作成していた https://github.com/skirino/croma に、 Mix.env の値によってコンパイル時に def として解釈するか、 defp として解釈するマクロがあります。 その使われ方が面白かったのでメモ。 その箇所だけ切り出して、参照値を環境変数のMIX_ENVにしたものが以下の Functions モジュールです。それをimportする Defpt モジュール、利用する Alexa と Alexaを呼び出す Me 。この Alexa で定義している defpt が今回の対象です。 これを見ると、 Me の中の Alexa.hello が、MIX_ENV == “test” の時はアクセス可能だけれど、それ以外ではundefined function errorになることがわかります。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review,…More

[Elixir]withとelseとguardsと。

Elixir 1.3では、 with に対して else や guards を使えるということで、少し試してみました。1.3の時と、1.2.4の時で無理やり書いた時。 http://tuvistavie.com/tokyo.ex 簡単な、 %{width: 10, height: 20} から値を取得して、それに対して幾つかのエラーケースを実践するという内容です。 1.3 さっとまとまる。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters…More

[Erlang][Elixir]erlyberlyでErlang/Elixirのdebugをサポート

Erlang/Elixirのdebugを楽にするツールを知ったのでメモ。 https://github.com/andytill/erlyberly http://blog.plataformatec.com.br/2016/04/how-to-trace-elixir-nodes-with-erlyberly/ 実行のワンライナーは以下。 これが全て終わって、JavaのGUIが表示されたら、例えば以下のようにnodeを指定してアプリを起動します。 起動後、Javaで表示されているtarget nodeに “foo@127.0.0.1” を指定。 すると、メモリ使用量とか、諸々を確認することができる以下のような画面を確認できるようになります。 以下は、この簡単なPhoenixアプリケーションに対して実行した時。 対象 https://github.com/KazuCocoa/web_qa_vote 以下は、http_proxyに対して。 対象 https://github.com/KazuCocoa/http_proxy いずれも、BEAM VMのprocessやatomなどのメモリ使用量が計測できてとても良いですね。atomがGCされないので、これが過度に大きいとメモリ圧迫している、とか簡単にわかりますし。あとはfunctionsの名前空間の形もパッと見ることができますね。 https://github.com/andytill/erlyberly#get-the-process-state にあるように、processの状態を抜くこともできるようです。 ある程度はObserverでも見ることができますが、メモリ使用量をこんな感じでグラフにしてくれるのは解りやすい。Java製。More

[Elixir]Structs, String-keyed Maps, Atom-keyed Maps

Elixirの実装を書いている時、データを保持したりする時にStructs、String-keyed Maps、Atom-keyed Mapsのどれを使えばいいかよく悩んでいました。今日も悩んでいて、何かベストプラクティスないかな、と考えていたところ、ちょうど私の考えと同じものがあったのでメモ。 それぞれは以下な感じで書くことができます。 BEAM VMにおいて、atomはCGされません。そのため、どうてきにatomを生成することは良くない、と知っていました。その上で、何が一番妥当なのかなーと思ってたら、以下ページが見つかりました。 https://engineering.appcues.com/2016/02/02/too-many-dicts.html ルールは以下。 1. Always Use String-Keyed Maps for External Data 2. Convert External Data to Structs ASAP 3. Use Structs in All Other Code 4. Use Structs for Output Data 5. Avoid Using Atom-keyed Maps That Aren’t Structs 6. Use Keyword Lists Only for Function Arguments Structsで定義していたら、 defprot や…More

[Elixir]PubSub機構をサクッとつくる

Elixirは receive があらかじめ用意されている。そのため、 send で特定のプロセスに送ったメッセージを受け取って、何らかの処理をするというコードが容易にかける。それを使い、PubSubをするコード。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters defmodule PubSubServer do def start(subscriber_callback \\ nil) do spawn…More

[Elixir]Keywordの中身はTupleのList

Elixirに置いて、Keyword listはTupleで表現される。 なので、 のようなパイプを書いた時、取得されるのは [“hello”] になる。 ここで、Elixir v1.2.3 の Keyword.valuesの中身を覗いてみると、以下のようにmapを適用した中でTupleからちょうどvalueを取得してListを作って返している。 当初、 しか Keyword 系は使えないと思っていたけれど、Erlangレベルでは なので、Keyword listとみなしてKeyword操作ができるのですね。学びだ。 蛇足だけれど、 Enum.any?/2 と言う、処理の途中で要素が見つかったらtrueを返す用途で使うfunctionも教えてもらった。なるほど。More

[Erlang][Elixir]Efficiency Guide User’s GuideでErlang/Elixirを知る

ErlangのEfficiency Guideが役立ったので、メモ。 Erlang/Elixirをやるなら知っておくべきことが多数ありました。 私が読んだのは、version 7.3 http://erlang.org/doc/efficiency_guide/introduction.html また、 http://erlang.org/doc/efficiency_guide/advanced.html にはAtomと言った型に対する制限であったり、メモリの制限などのまとまった情報を得ることができます。他、List操作に対する注意ごとや、tail recuesiveにすることの良さなど。More