Phoenix with Elm をやってみた Part4

Part3から続きまして Phoenix with Elm をためしてみましたのでメモ書きとして残しておきます。
本日は Phoenix with Elm の Type annotations を行っていきます。

今回は、関数へ引き渡す引数の型注釈についてです。
Part3にて引数にて変数の引き渡しを行いましたが、特に型については気にせずに引き渡しておりました。
しかしコードを読む際に引き渡す型がわからないとコードが読みにくいなどありますので型注釈を行っていってみましょう。

ソースコードの流れから読んでいきましょう。ソースコードの全体に関しましては、Github上で確認することができます

まずは、main についてです。
main では引数を受け取っていないため、戻り値として HTML の String型を返すことが記載されております。

main : Html String

init ファンクションです。
init でも引数は受け取っておらず。戻り値は Model を返すことを記載しております。

init : Model

続いて view です。
こちらは、引数として Model を受け取り、返す値は Html の String型を返すことが記載されております。
View は Model を受け取り、受け取った Model を使用して、Html を表示し、戻りとして Html の String型となっている。
流れとしてわかりやすく記載されているのではないでしょうか。

view : Model -> Html String

最後に seatltem メソッドは Seat型 を受け取り、Html の String を返すように記載を追加しております。

seatItem : Seat -> Html String

今回は、型注釈を追加したのみですので、実際に実行しても表示は Part3 で表示した内容とは変わりません。

それでは今回は終わりとなります。
今回は型注釈を追加したのみですので難しいことは何もなかったのではないでしょうか。
それでは次回もありましたら宜しくお願いいたします。

Phoenix with Elm をやってみた Part3

Part2から続きまして Phoenix with Elm をためしてみましたのでメモ書きとして残しておきます。
本日は Phoenix with Elm の Adding a Model and enhancing the View を行っていきます。

今回はModelを追加して、Viewの表示を表示しやすくしていきます。
前回に記載されておりますが、Elmでは、Modelは アプリケーションの状態を保持する処理を行い、Viewにて処理した状態を表示するための処理を記載いたします。


ソースコードの流れから読んでいきましょう。ソースコードの全体に関しましては、Github上で確認することができます

main = 
  view init

main にて view を呼び出す際に view のパラメータとして init を付加して引き渡しております。
そのため、下記の init にて定義されている値が view に引き渡されることとなります。

init =
  [ { seatNo = 1, occupied = False }
  , { seatNo = 2, occupied = False }
  , { seatNo = 3, occupied = False }
  , { seatNo = 4, occupied = False }
  , { seatNo = 5, occupied = False }
  , { seatNo = 6, occupied = False }
  , { seatNo = 7, occupied = False }
  , { seatNo = 8, occupied = False }
  , { seatNo = 9, occupied = False }
  , { seatNo = 10, occupied = False }
  , { seatNo = 11, occupied = False }
  , { seatNo = 12, occupied = False }
  ]

init にて定義されている値が引き渡されるのはわかったかもしれませんが、その値の定義はどこで行われているかと言いますと、下記のコードの部分にて定義が行われております。

type alias Seat =
  { seatNo : Int
  , occupied : Bool
  }

type alias Model =
  List Seat

Modelとして List の Seat をまずは定義しております。
では、Seatの定義はと言いますと、 alias にて seatNo というInt型と occupied という Bool型の定義であることがコードから読み取れます。

最後に Viewにて引き渡されたモデルを ul や li タグにて表示するように記載されております。

view model =
  ul [ class "seats" ] (List.map seatItem model)

seatItem seat =
  li [ class "seat available" ] [ text (toString seat.seatNo) ]

いつもどおり iex -S mix phoenix.server の実行後に
http://localhost:4000 にアクセスしてみましょう。
List.map にて引き渡されたModelの個数分だけ表示を行っているため、下記の画像のように 12個分のシートが表示されるようになっております。


以上となります。
以前に追加した cssで表示が行われている部分もあり、目に見えない部分も多くあるとは思いますが、ElmにてModel と View での使用方法がわかる内容ではないかと思います。

それでは、次回の更新が続けられることを願い、お別れとなります。

Phoenix with Elm をやってみた Part2

昨日から続きまして Phoenix with Elm をためしてみましたのでメモ書きとして残しておきます。
本日は Phoenix with Elm の Adding a simple View を行っていきます。

まずは、css と 画像ファイルの追加を行っていきます。
下記のディレクトリにリンク先のファイルを配置していきます。

web/static/css/seatsaver.css
web/static/assets/images/seat.png

上記のファイルは画面表示のために使用するだけなので、特にきにする必要はありません。

今回は、Elmの標準的なアーキテクチャのパターンとしては下記のように
Model - Update - View の形式での記載を行っていきます。
それぞれ下記ように使用していくようです。

Model:アプリケーションの状態を保持する処理
Update:アプリケーションの状態の更新を行う処理
View:HTMLなどの表示の処理

import Html exposing (..)

-- MODEL

type alias Model = .....

-- UPDATE

update = ....

-- VIEW

view = ...

上記のように Model - Update -View の順番に記載していくのが標準的なパターンのようです。
こちらは guide.elm-lang.org の The Elm Architecture にも記載されております。

さて、今回の更新内容ですが VIEWの追加のみを行っていきます。
VIEWはHTMLなどの表示の処理を実施しますので "Woo hoo, I'm in a View" を表示するように変更します。
昨日、記載していた SeatSaver.elm を変更していきます。

web/elm/SeatSaver.elm

main =
  view

-- VIEW

view =
  Html.text "Woo hoo, I'm in a View"

昨日のコードでは、main にて Html.text を呼び出しておりましたが、今回のソースコードでは view で呼び出しを行っております。
違いとしては、それぐらいとなります。

昨日と同じく、 iex -S mix phoenix.server の実行後に
http://localhost:4000 にアクセスし、 Woo hoo, I'm in a View と表示されていれば成功です。
css と 画像の追加を行っていた場合には Woo hoo, I'm in a View の周りに灰色の枠も追加されているかと思います。

以上となります。
さて、Elm のアーキテクチャに合わせて記載方法の変更を行うようになってきました。
次はどのような変更を行っていくのでしょうか。

Phoenix with Elm をやってみた Part1

Phoenix With Elm をためしてみましたのでメモ書きとして残しておきます。
Phoenix With Elm全体が気になる方は下記をごらんください。

Phoenix with Elm
Phoenix with Elmのリポジトリ

#実行環境
OS:OS X Yosemite
Erlang v19.0
Elixir v1.3.2
Phoenix v1.2.0
Elm v0.7.1
Node v6.2.2

ElmはJavaScriptコンパイルされる関数型言語です。
Elm自体は既にインストールされていることを前提として進めております。
Elmlang.org にてインストール方法を確認していただければ、特に問題なくインストールは終わるかと思います。

まずは、Phoenixのアプリケーションを作りましょう。
ここは特にきにすることはなく、いつも通り作っていただいて問題はありません。

$ mix phoenix.new phoenix_with_elm
$ cd phoenix_with_elm/
$ mix ecto.create

続いて、Elmのコードを配置する場所の作成を行います。
web配下にelmディレクトリを作成し、その下にコードを作成していくようです。

$ mkdir web/elm

web/elm 配下に SeatSaver.elm という名前でElmのコードを記載します。
Elmには、Htmlのコアライブラリとして htmlというライブラリがあります。
こちらをインポートして、Hello from Elm という文字列を main に渡しているようです。
web/elm/SeatSaver.elm

module SeatSaver exposing (..)

import Html

main = Html.text "Hello from Elm"

さて、elm自体のコードの記載は終わりましたので、json の用意をしていきます。
jsonにてelmパッケージの管理を行うための記載を行っていきましょう。
package.json

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "brunch build --production",
    "watch": "brunch watch --stdin"
  },
  "dependencies": {
    "babel-brunch": "~6.0.0",
    "brunch": "~2.1.3",
    "elm-brunch": "~0.7.0",
    "clean-css-brunch": "~1.8.0",
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html"
  },
  "devDependencies": {
    "babel-brunch": "~6.0.0",
    "brunch": "2.7.4",
    "clean-css-brunch": "~2.0.0",
    "css-brunch": "~2.0.0",
    "elm": "^0.17.1",
    "javascript-brunch": "~2.0.0",
    "uglify-js-brunch": "~2.0.1"
  }
}

brunch-config.json

  ...
  // Phoenix paths configuration
  paths: {
    // Dependencies and current project directories to watch
    watched: [
      "web/static",
      "test/static",
      "web/elm/SeatSaver.elm"
    ],

    // Where to compile files to
    public: "priv/static"
  },

  // Configure your plugins
  plugins: {
    elmBrunch: {
      elmFolder: "web/elm",
      mainModules: ["SeatSaver.elm"],
      outputFolder: "../static/vendor"
    },
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/web\/static\/vendor/]
    }
  },
  ...

さて、パッケージの管理のための記載が行えましたので、次はHTML側の準備を行っていきましょう。
Phoenixの基本ページである index.html.eexの内容を変更していきます。
自動生成された内容を削除し、下記を記載します。
web/templates/page/index.html.eex

<div id="elm-main"></div>

さて、続いてapp.js内部にelmの読み込みの記載を行います。
elmはelmで記載されたコードをJavaScriptに変更しますので、その内容をapp.jsにて読み込んで実行していきます。
web/static/js/app.js

...
const elmDiv = document.getElementById('elm-main')
    , elmApp = Elm.SeatSaver.embed(elmDiv)

最後にテンプレートの記載を行って完了です。
web/templates/layout/app.html.eex

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Hello SeatSaver!</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

  <body>
    <div class="container">

      <main role="main">
        <%= render @view_module, @view_template, assigns %>
      </main>

    </div> <!-- /container -->
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>

さて、最後に実行すればおわり…かと思いましたら、そうはいきませんでした。
どうやらbabel2015とbabel2016の対応をしなければElmのコンパイルに失敗してしまうようなので、npm installにて実行しましょう。
環境が変わったりすると実際に試してみないとわからないことですね。
compiled seatsaver.js と表示され、seatsaver.js がコンパイルされれば、問題はないはずです。

$ npm install babel-preset-es2015
$ npm install babel-preset-es2016
$ iex -S mix phoenix.server
Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

[info] Running PhoenixWithElm.Endpoint with Cowboy using http://localhost:4000
Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Elm compile: SeatSaver.elm, in web/elm, to ../static/vendor/seatsaver.js 
19 Sep 20:40:28 - info: compiled 8 files into 2 files, copied 3 in 1.6 sec
19 Sep 20:40:29 - info: compiled seatsaver.js and 5 cached files into app.js in 175ms

http://localhost:4000 にアクセスし、 Hello from Elm と表示されていれば成功です。

Elm自体のコードの書き方は guide.elm-lang.org をみていただければ、どのように記載していくのかがわかるかと思います。
これから少しずつ Phoenix with Elmを続けて参考資料をあげていけれるように頑張ります。

ElixirChanges-20160522

c0b:7efc40016ad81e07d365c33c72f8d4bc44d6a399

(#4412)
ファイル名

lib/elixir/lib/option_parser.ex
lib/elixir/test/elixir/option_parser_test.exs

:countr をサポートするために option_parser.ex の改善が行われました。
:countr があることにより同一の指定オプションの個数を持つようです。

josevalim:9785e3667846ce3040d5d8d7f507d80e806a3af0

ファイル名
lib/mix/test/fixtures/no_mixfile/lib/c.ex
lib/mix/test/mix/tasks/compile.elixir_test.exs
lib/mix/test/mix/tasks/compile_test.exs
lib/mix/test/mix/tasks/deps.git_test.exs

no_mixfile から cモジュールが削除されました

josevalim:9d4d84df5dbefe37251d38279ff7a594bb9c4dc9

ファイル名
lib/elixir/lib/option_parser.ex

ドキュメントの改善が実施されました。

milmazz:3f814349fd15a38d1a82e2605ab4e04ebec9d66d

ファイル名
lib/elixir/lib/option_parser.ex
lib/elixir/test/elixir/option_parser_test.exs

OptionParser に parse!/2 と parse_head!/2 メソッドが追加されました。
parse!/2 や parse_head/2 では無効なオプションが指定されていた場合に OptionParser.InvalidOptionError が発生します。

josevalim:cae9875ca7ee54eafb637954199d8df5cf866b15

ファイル名
lib/ex_unit/lib/ex_unit/doc_test.ex
lib/ex_unit/test/ex_unit/doc_test_test.exs

ドキュメントのテストの改善が行われました。

josevalim:91aa29d1b47a110572b45bb846453a87fac519b7

ファイル名
lib/elixir/lib/option_parser.ex
lib/elixir/test/elixir/option_parser_test.exs

上記の OptionParser.InvalidOptionError ですが ParseError へと変更が行われました。

josevalim:6a8e788b8256d485ddb8295deca0d030636518ef

ファイル名
lib/elixir/lib/option_parser.ex

引数不足の場合の例外メッセージが追加されました。

josevalim:92f87b6b17b9272fc79e2f8fb94557805e6c2063

ファイル名
lib/mix/lib/mix/task.ex
lib/mix/test/mix/task_test.exs
lib/mix/test/test_helper.exs

Mix.Task にて OptionParser.ParseError を取得したら Mix.Error へと変換する処理が入りました。

josevalim:4e648199f18ee3be8addab82c951b9e2dd82f885

ファイル名
lib/mix/lib/mix/local/installer.ex
lib/mix/lib/mix/tasks/app.tree.ex
lib/mix/lib/mix/tasks/archive.build.ex
lib/mix/lib/mix/tasks/escript.build.ex
lib/mix/lib/mix/tasks/escript.install.ex
lib/mix/lib/mix/tasks/local.public_keys.ex
lib/mix/lib/mix/tasks/new.ex
lib/mix/lib/mix/tasks/profile.fprof.ex
lib/mix/lib/mix/tasks/run.ex
lib/mix/lib/mix/tasks/test.ex
lib/mix/test/mix/tasks/new_test.exs
lib/mix/test/mix/tasks/profile.fprof_test.exs

build や Profile に 新しく @switches にてオプションが追加され、そちらをチェックしてからの 実行を行うように変更されました。

antipax:0395bac1c165962e1e01cabd73ed92569ca925ed

(#4639)
ファイル名

lib/elixir/lib/kernel/lexical_tracker.ex
lib/elixir/lib/protocol.ex
lib/elixir/src/elixir_dispatch.erl
lib/elixir/src/elixir_exp.erl
lib/elixir/src/elixir_lexical.erl
lib/elixir/test/elixir/code_test.exs
lib/elixir/test/elixir/kernel/lexical_tracker_test.exs
lib/mix/lib/mix.ex
lib/mix/lib/mix/compilers/elixir.ex
lib/mix/lib/mix/tasks/compile.ex
lib/mix/lib/mix/tasks/compile.xref.ex
lib/mix/lib/mix/tasks/xref.ex
lib/mix/test/mix/tasks/compile.xref_test.exs
lib/mix/test/mix/tasks/compile_test.exs
lib/mix/test/mix/tasks/xref_test.exs

コンパイル時に解決できないリモート呼び出し時の問題をあげるように変更が加わったようです。

Erol:ee715dd49df15cf0f24c66643219b6b2ec50c8f9

#4658)
ファイル名

lib/mix/lib/mix/local.ex

メソッド名がtypoしていたためメソッド名の変更と使用している箇所の修正が行われました。

josevalim:94b0406fb70f5d565263426e2ed122704525bea6

ファイル名
lib/mix/lib/mix/compilers/elixir.ex
lib/mix/lib/mix/tasks/compile.xref.ex
lib/mix/lib/mix/tasks/xref.ex
lib/mix/test/mix/tasks/xref_test.exs

mix xref のための --warnings と --unreachable オプションが新規に追加されました。

josevalim:94b0406fb70f5d565263426e2ed122704525bea6

ファイル名
lib/elixir/lib/kernel/lexical_tracker.ex

Store runtime と lexical tracker の状態で直接コンパイルを実施できるように改善が実施されたようです。

ElixirChanges-20160520

antipax:28caafb164d1ab74630ea71747005593c7f0c0e3

(#4647)
ファイル名

lib/mix/lib/mix/compilers/elixir.ex

elixir コンパイル時にモジュール名がコンパイル時に有効であるか確認をしていないため、manifest にてファイルやモジュールが別の存在であるように分離されたようです。

josevalim:45f0d076c54deb5f1cbb78d3911045bc8a511245

ファイル名
lib/mix/lib/mix/compilers/elixir.ex

上記で分離されたマニフェストですが、sources と files は統合されました。

antipax:93394ce960e3a22f7cd905f6493140e23d1c991c

(#4651)
ファイル名

lib/elixir/lib/kernel/lexical_tracker.ex

Kernel.LexicalTracker にて、今まで ETS を使用していた箇所が map へと置き換わりました。

britto:ab5e46ba625f7f62f99286a3fb48d010a292fa2c

(#4649)
ファイル名

lib/ex_unit/lib/ex_unit/callbacks.ex
lib/ex_unit/lib/ex_unit/case.ex
lib/ex_unit/test/ex_unit_test.exs

async tag は ExUnit.Case が使用されている時間によって設定されることを想定されているため無効なオーバライドは無効になるように修正が入ったようです。

wojtekmach:3dcb1b79ba360965cd65532f0694554e5885f58f

(#4653)
ファイル名

lib/elixir/lib/kernel/lexical_tracker.ex

ドキュメントの不要部分が削除されました。

andrewtimberlake:ede00a1460c9ea845c8360933da5a414ca8f0c2d

(#4644)
ファイル名

lib/elixir/lib/uri.ex
lib/elixir/test/elixir/uri_test.exs

URI.merge/2 メソッドが新規に追加されました。

whatyouhide:db9066c5f0d17c373bd8a857e88b26f336247d30

(#4648)
ファイル名

lib/elixir/lib/supervisor.ex
lib/elixir/lib/supervisor/spec.ex

ドキュメントの改善が実施されました。

whatyouhide:db9066c5f0d17c373bd8a857e88b26f336247d30

(#4652)
ファイル名

lib/elixir/lib/gen_server.ex

ドキュメントの改善が実施されました。

whatyouhide:db9066c5f0d17c373bd8a857e88b26f336247d30

(#4652)
ファイル名

lib/elixir/lib/uri.ex

ドキュメントの改善が実施されました。

ericmj:2cf19c705d1e3b9db3d013e754081606e7acda70

ファイル名
lib/elixir/lib/list.ex
lib/mix/lib/mix/tasks/deps.compile.ex
lib/mix/test/mix/rebar_test.exs

rebar3 の出力に関して色つき出力にならないように修正が入ったようです。

ericmj:ecf419e19b4426d0e938d90241504061b5416871

ファイル名
lib/mix/lib/mix/rebar.ex
lib/mix/test/mix/rebar_test.exs

rebar3 にて パッケージ名から depsできるようにメソッドが追加されました。

PhoenixframeworkChanges-20160520

chrismccord:d3fce7f4ca95894ec926d4184e3cb7454856393c

ファイル名
installer/templates/new/config/dev.exs
lib/phoenix/endpoint/adapter.ex

watchers のPathの設定が Path.dirname は非推奨となり、Path.expandを使うようになりました。

chrismccord:28cecca20abc9bf30f69400acd7a1c3ac8564e16

ファイル名
CHANGELOG.md
lib/phoenix/endpoint/watcher.ex

watcher の設定用に最後に :cd を追加するむねの記載が追加されました。

jamescmartinez:c073ebc7d61e17fcdd5ac24e644d31e7dd4db04b

(#1717)
ファイル名

installer/templates/ecto/model_case.ex

Ecto 2.0.0 のエラーの設定の反映作業が実施されました。

nicholaswyoung:4812a704bac99734deb3b77e5b60e67a2af6874a

(#1718)
ファイル名

package.json

NPMに記載するための説明とライセンスについての記載が追加されました

jamescmartinez:7c81e1ca374f1a6bf06bf9d81a716202713b17f2

(#1717)
ファイル名

installer/templates/ecto/model_case.ex

Ecto 2.0.0 のエラーの設定 の対応で、ErrorHelpers.translate_error/1 が良いため変更が行われました。

chrismccord:7870780a00746c45df03d41a4f2d10b02cb81d00

(#1715)
ファイル名

lib/phoenix/endpoint/adapter.ex
lib/phoenix/endpoint/watcher.ex

watcher にて File.cwd! の動作がデフォルトの動作へと変更されたようです。

chrismccord:3e7736af0b47b81ce8afaac47cebdf2b20fb00f3

ファイル名
installer/templates/ecto/model_case.ex

Ecto 2.0.0 のエラーの対応ですが、フォーマットが変更され、Enum.flat_map が使われるように変更が入りました。