個人的なメモです。 Elixirでの、pin演算子の意義として以下の返答をもらいました。 確かに、個人的に明示的にパターンマッチと知らせるために ^x = 1 のように書かせることに利点があるという言語設計、納得。More
Category Archives: other
[Elixir][Phoenix]has_oneやbelongs_toの関係にあるモデルを、他方のモデル生成時に合わせて生成する
has_one や belongs_to の関係になっているDeviceとUserのモデルを考えた時に、Device作成時にUserモデルも新規に作成したい時の話。 このメソッドは対象は、Phoenixのcreateリクエストを元にしています。 Rep.transaction とその中で依存性を持つ複数のDB処理を一括で書いています。 has_one や belongs_to の関係を持っているので、一方の _id に、もう一方の id を与える必要がある、ところがポイント。 もっとちゃんとした書き方あるのかな。ありそうな気がする。。。 この関係が正しくできているかは、controllerレベルでは以下のように適当なユーザを生成して、その上でindexなどが表示できることを確認すればOK。 この時、index.htmlでは device.user.user_name のような、has_oneの関係にある要素を描画しようとしていることが必要ですが。 Railsに似ているので、Railsも参考にしながら書いてみているけれど、DB周りの扱いがだいぶ想像できるようになってきた感じ。 まだ公開していないけれど、練習用repositoryはこちらMore
[Elixir]引数で与えられた関数を実行する
Elixirで、引数として関数 fn を与えた時、その与えられた関数を実行する方法がぱっと調べただけでは見つからなかったのでメモ。 以下のように、 f.() という形式で、与えられた引数としての関数を実施できるようですね。 簡単なサンプル もう少し進んで、exercismから同様な問題があったのでそれを使って見てみます。 テストコード 実行コード Rubyでいう、 yield を呼び出すのをElixirでは .() で行うのですね。 参考: http://hashrocket.com/blog/posts/elixir-functions-ruby-lambdasMore
[Elixir]Pin演算子のちょっとした確認
ElixirにはPin演算子があって、その挙動を少し頭に入れるために簡単なcase文をつくってみました。 Pin演算子は、変数の再代入を防ぐ、という役割を持ちます。 以下は引数として与えられた a が、 SamplePin.pin1(a) ではcase文では b=10 が再代入される SamplePin.pin2(a) ではcase文で b=10 が再代入されず、パターンマッチされる という例です。 Erlangの流れを持ちますが、再代入が許容されるElixirでの再代入という副作用を防ぐ手段ですね。More
[Elixir]belongs_toしているモデルのcontrollerのテストコードを修正する
belongs_toの関係を持つモデルを、 #show で描画するところのcontroller層の話です。そのとあるコードをテストする時、従属の関係にあるモデルをDBに生成しておく必要があるのですが、そのコードを書くにあたりEctoの知識が欠如しててつまづいていたけれど、うまくかけた、というメモ。 Userモデルは、Pageモデルの一部に従属(belongs_to)しているので、Userモデルの要素を取得する場合、PageモデルをDBに生成しておく必要がある、というコードです。 以下のshowがテスト対象となるもので、UserのRepoを取得してきて、それに対してSQLの IN (Repo.preload)をしてきて、その結果を描画するという内容。 それに対して、Repo.insertでPageを作成、その次に従属の関係を作るためにpage_idに生成したpageのidを代入したUserを用意する。 最後に、Repoを更新すると、最低限のデータが揃うので、showで表示する要素としては十分なデータが揃えられる、というものです。 Ectoの理解があるとひょいひょいっとできるのですが、そこが欠如していた時はどう書けば良いかよくわからなかったのですよね…More
[Elixir]Ectoを触ってみる
Elixirの軽量なORMであるEcto それの使いかたをざっと把握していくために少しEctoを触ってみました。 メモです。 対象 標準的なクエリ とか これらはいずれも、以下のようなクエリが発行される。 パイプで接続されたEcto.Queryはクエリを結合していくのですね。 他、以下のようにlimitをかけることも可能。 preloadを行う belongs_to などで関係を持った、異なるテーブルに対してクエリを投げる場合、以下のようにpreloadを使います。 Ecto.Repo#preload/2 は、以下の通り IN で統合したテーブルに対してクエリを投げるのですね。この時に発行されるクエリは以下。 なるほど。More
[Elixir]Plugのコードを少し読んでみる
PhoenixのPlugの説明を読んでいると、Plug自体の動きが少し気になったので読んでみました。 ここでは、以下の Hello World を追ってみることに。 https://github.com/elixir-lang/plug API Document: http://hexdocs.pm/plug/ Plug自体、簡単なWebサーバの機構を提供するものですね。 ひとまず、 を実行してみる。 まずは以下が呼ばれる。 https://github.com/elixir-lang/plug/blob/master/lib/plug/adapters/cowboy.ex#L41 この中を辿ると、 run(:http, plug, opts, cowboy_options) にいきつく。 ここで何しているかを見てみる。 https://github.com/elixir-lang/plug/blob/master/lib/plug/adapters/cowboy.ex#L118 なるほど。最終的に、Cowboyを実行しているのですね。これはErlang向けの軽量なWebサーバらしい。 Cowboy https://github.com/ninenines/cowboy 返り値として、 {:ok, pid} のタプルを返す。 試しに、もう一度実行すると以下のようにerrorを得られる 今度は :error のタプルですね。:already_started が得られているので、pidを得たい場合、 とすれば得られます。なるほど。 ちなみに、停止するときは、 とします。 これは、 https://github.com/elixir-lang/plug/blob/master/lib/plug/adapters/cowboy.ex#L96 を参考にすれば良いですね。ここで与える :ref は、起動時に与えた Plug.Adapters.Cowboy.http MyPlug, [] の中の MyPlug という名前。 これは、以下のコードを見てみると、確かに:refの引数( build_ref(plug, scheme) )としてplugを与えているのでわかります。 https://github.com/elixir-lang/plug/blob/master/lib/plug/adapters/cowboy.ex#L35 なるほど。Plugというか、Cawboyの理解が少し進んだぞ。 %Plug.Conn{}…More
[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