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 が良いため変更が行われました。