スポンサーリンク

2015年6月14日

TrotのREADME.mdを翻訳してみた。

#目的

TrotのREADME.mdを翻訳する。

#実行環境

OS:Windows8.1
Trot Framework: v0.5.0 or v0.6.0

#目次

1. README.md翻訳
2. まとめ

#参考文献

https://github.com/hexedpackets/trot

#始める前に

注意!!
この記事は、trotのREADME.mdをyahoo翻訳の力を借り、素人翻訳した内容を書いています。
管理人の英語力は本人がドン引きするほど低いので、
間違った解釈及び理解している部分が多分にあると思います。
それでも構わないという方は見て頂けたら嬉しいです。

また、ご指摘等があれば受け付けておりますゆえ、遠慮なくお願いします。
特に間違えて習得している部分は教えて頂ければ、本当に助かります。

以下の部分は全て原文から引用している部分です
>英文

CHANGELOG.mdを見るとv0.5.0までしか書いてないけど、
VERSIONのファイルを見るとv0.6.0と書いてある。
どっち正式だ?書いてるだけでv0.6.0じゃない?CHANGELOG.mdを更新してないだけ?

追記(2015/06/14)
無事、Hello World的なもの出せました。
[Elixir+Trot] Trotフレームワークを使って"Hello Trot!!"するだけの簡単なお仕事・・・

##1. README.md翻訳


-trot

>Trot is an Elixir web micro-framework based on Plug and Cowboy.
>The goal of Trot is to make common patterns in Plug easier to use,
>particularly when writing APIs, without sacrificing flexibility.

Trotは、PlugとCowboyを基本としたElixirのWebマイクロ・フレームワークです。
特にAPIを記述する時、Trotの目的はPlugの柔軟性を犠牲にすることなく一般パターンをより使いやすくすることです。

-Usage
>Add Trot as a dependency to your mix.exs file and update your applications list to include it.

あなたのmix.exsファイルへ依存関係Trotを加えて、あなたのアプリケーション・リストを更新して下さい。
----
defp deps do
  [{:trot, github: "hexedpackets/trot"}]
end

def application do
  [applications: [:trot]]
end
----

>The following configuration options are supported by the server:

以下の構成オプションは、サーバでサポートされています。

>config :trot, :port, 4000: port to listen on for incoming HTTP requests. Defaults to "4000".
>
>config :trot, :router, MyApp.Router: module to route requests to. Defaults to "Trot.NotFound".
>
>config :trot, :heartbeat, "/heartbeat": path to setup a heartbeat route.
>This will always return 200 with a body of "OK". Defaults to "/heartbeat".
>
>Finally, put use Trot.Router to the top of your module.
>This will add route macros and setup the plug pipeline at compile time.

config :trot, :port, 4000:
HTTPリクエストを受けるポートの設定。デフォルトは4000番。

config :trot, :router, MyApp.Router:
リクエストを送るモジュールを設定。デフォルトは"Trot.NotFound"

config :trot, :heartbeat, "/heartbeat":
heartbeatのルートパスを設定。これは、常にbodyにOKと200が戻ります。デフォルトは"/heartbeat"

最後に、"use Trot.Router"を置いてください。あなたのモジュールの上部へ。
これはルート・マクロを加えます、そして、セットアップがコンパイル時のプラグ・パイプラインです。

最後に、一番上へあなたのモジュールを置いて"use Trot.Router"して下さい。
これは、ルートマクロへ加えています。そして、コンパイル時にプラグパイプラインをセットアップします。

-Routes
>Routes are specified using one of the HTTP method
>macros: get/3, post/3, put/3, patch/3, delete/3, options/3.
>The first argument is a the path to route to,
>the second (optional) argument is a keyword list of any options to match against,
>and the last argument is the block of code to execute. Examples are below.
>
>If @path_root is specified, it will be prefixed to all routes in that module.
>
>Routes can be setup in different modules and imported into the main router
>with the import_routes/1 macro,
>which takes a module name as the only argument.
>Note that ordering matters as normal Elixir pattern matching rules apply to imported routes.
>
>A default 404 response can be enabled by putting import_routes Trot.NotFound or
>use Trot.NotFound at the end of the module.

ルートに指定して使えるHTTPメソッドのマクロ: get/3, post/3, put/3, patch/3, delete/3, options/3。
第一引数はルートのパス、第二引数はキーワードリストの幾つかのオプションに対してマッチする。
最後の引数は実行するコードのブロックです。
下記は例です。

もし"@path_root"を指定したら、それはモジュールの中の全てのルートにプレフィックスが付きます。

ルートは異なるモジュールでのセットアップがありえます。
それは、"import_routes/1"マクロでメインルータにインポートされます。
それは、唯一の引数としてモジュール名を取ります。
オーダが重要である点に注意して下さい。通常のElixirパターンマッチ規則としてインポートされたルートにapplyして下さい。

デフォルト404のレスポンスは、"import_routes Trot.NotFound"で許可するかモジュールの終わりに"use Trot.NotFound"でできます。

-Responses
>All of the following are valid return values from handlers and
>will be parsed into full HTTP responses:
>
>- String of response body
>- Status code, either numeric or an atom from Plug.Conn.Status
>- {code, body}
>- {code, body, headers}
>- JSONable object
>- {code, object}
>- {code, object, headers}
>- {:redirect, location}
>- {:badrpc, error}
>- %Plug.Conn{}

以下の全ては、ハンドラーからの有効な戻り値でフルHTTPレスポンスに解析されます。

- String of response body
- Status code, either numeric or an atom from Plug.Conn.Status
- {code, body}
- {code, body, headers}
- JSONable object
- {code, object}
- {code, object, headers}
- {:redirect, location}
- {:badrpc, error}
- %Plug.Conn{}

#Example router application

----
defmodule SoLoMoApp.Router do
  use Trot.Router

  # Returns an empty body with a status code of 400
  get "/bad" do
    :bad_request
  end

  # Sets the status code to 200 with a text body
  get "/text" do
    "Thank you for your question."
  end

  # Redirect the incoming request
  get "/text/body", headers: ["x-text-type": "question"] do
    {:redirect, "/text"}
  end

  # Sets the status code to 201 with a text body
  get "/text/body" do
    {201, "optimal tip-to-tip efficiency"}
  end

  # Sets status code to 200 with a JSON-encoded body
  get "/json" do
    %{"hyper" => "social"}
  end

  # Pattern match part of the path into a variable
  get "/presenter/:name" do
    "The presenter is #{name}"
  end

  import_routes Trot.NotFound
end
----

#Templating
>To add templating in a router,
>add use Trot.Template and set @template_root to the top-level directory
>containing your templates.
>By default, @template_root is "templates/".
>
>Trot can be used to render EEx templates (the default engine include with Elixir),
>HAML templates through Calliope, or a combination of both.
>When the application is compiled a render_template/2 function is
>generated for every template under @template_root.
>render_template/2 expects the name of the template
>relative to @template_root as the first
>argument and a keyword list of variables to assign as the second argument.
>
>When MIX_ENV=prod all of templates are loaded and pre-compiled for faster rendering.

ルータにテンプレートを加えるために、"use Trot.Template"を加え、
"@template_root"であなたのテンプレートをトップレベルのディレクトリに設定して下さい。
デフォルトでは、"@template_root"は"templates/"です。

Trotは、EEXテンプレートをレンダリングすることができます。
(デフォルトエンジンではElixirを含みます)
カリオペを通してHamlテンプレートか両方の組み合わせができます。
アプリケーションがコンパイルされる時、"render_template/2"関数は"@template_root"の下であらゆるテンプレートに生成されます。
"render_template/2"は、最初の引数と第二引数として割り当てる変数のキーワードリストとして"@template_root"と比較して名前をテンプレートに期待します。
"MIX_ENV=prod"が速いレンダリングのため全てのテンプレートをロードしてプレコンパイルする。

-Example app using templates
----
defmodule PiedPiper do
  use Trot.Router
  use Trot.Template
  @template_root "templates/root"

  get "/compression/pied_piper" do
    render_template("compression_results.html.eex", [weissman_score: 5.2])
  end

  get "/compression/nucleus" do
    render_template("compression_results.html.haml", [weissman_score: 2.89])
  end
end

# compression_results.html.eex
<html><body>Pied piper has a Weissman Score of <%= @weissman_score %></body></html>

# compression_results.html.haml
%html
  %body Nucleaus has a Weissman Score of <%= @weissman_score %>
----

-API versioning
>Adding use Trot.Versioning to your module will enable API version parsing and
>pattern matching.
>The first part of the path for all requests in the module is assumed to be the version.
>It is parsed into the conn[:assigns] dictionary, making it easy to access.
>Routes can also be configured to only match a particular version.

"use Trot.Versioning"をモジュールに加えるとAPIバージョン分析とパターンマッチを可能にします。
モジュールの全てのリクエストのためのパスの最初の部分はバージョンであるとされます。
それは、"conn[:assigns]"に解析されます、アクセスするのを簡単にする。
ルートは、特定のバージョンにだけにマッチするように構成されることもできる。

-Example versioned app
----
defmodule Nucleus do
  use Trot.Router
  use Trot.Versioning

  get "/version" do
    conn.assigns[:version]
  end

  get "/current", version: "v1" do
    :ok
  end

  get "/current" do
    :bad_request
  end
end
----

>In the above example, "/v1/version" will return "v1" as the response body.
>A request to "/v1/current" will return a 200 but "/v2/current" will return a 400.

上記の例において"/v1/version"は、レスポンスとして"v1"を返します。
"v1/current"へのリスエストは200を返します。しかし、"/v2/current"は400を返します。

##2. まとめ

やっぱり翻訳は面倒くさい。
一日掛かってしまった。

#管理人の独り言~

正直思った。翻訳しなくて良かったんじゃね?
README見れば実行するのはそんなに難しくない。

動きません・・・サンプルのソースコードを記述してもコンパイルエラーが出ます。
また、私の知識不足か起動方法さえ分かりません。
なので、デフォルトのページ(があれば)も表示できませんでした。
もう少し情報を探すか待ってみます。

それまでは、RailsチュートリアルをPhoenixで書き換えて実施して行こうと思います。

翻訳は、yahoo翻訳に切り替えました。
(一番理解しやすい英語→日本語に変換してくれる気がする・・・)
翻訳は"Google Translator Toolkit"を使います。
こんなのあったの知らなかった・・・

2015年6月13日

Elixir+Phoenix+MongoDBで掲示板(もどき)を作るだけの簡単なお仕事!

#目的

Elixir+Phoenix+MongoDBを使って掲示板(もどき)を作成する。


#実施環境

OS: Windows8.1
Erlang: Eshell V6.4
Elixir: v1.0.4
Phoenix Framework: v0.13.1
elixir-mongo: v0.5.1
MongoDB:v3.0.3

#目次

1. 作業一覧
2. ソースコード一覧
3. まとめ

#参考文献

なし!!

#始める前に


また、掲示板(もどき)を作成します。
個人的には一番作成が簡単で基本機能のおさらいになると思っているので・・・
毎度、新しい言語とWebフレームワークを使う時は私の恒例行事となっています(笑)

プロジェクトは以下の通り作成した。
>cd プロジェクト作成ディレクトリ
>mix phoenix.new phoenix_bbs
>cd phoenix_bbs
>mix phoenix.server (localhost:4000)
>Ctrl+c

MongoDBのインストール&起動、依存関係へmongoの追加等・・・
MongoDBの実行環境はご自身で整えておいて下さい。

##1. 作業一覧

-プロジェクト作成

-/web/router.exへスコープとルーティング先を追加
  -アクションは"index"と"create"

-新規のコントローラ作成
  -フォームの入力値を取得
  -リダイレクトの設定
  -indexアクションにコレクションの内容を全表示する処理を追加
  -createアクションにコレクションへ入力内容を挿入する処理を追加

-新規のビュー作成

-新規のテンプレート作成
  -レンダリングするディレクトリを作成
  -レンダリングするテンプレートを作成
  -テンプレートにフォームを追加
  -フォームを使ったページ遷移
  -データを繰り返して表示する処理を作成

-MongoDB
  -MongoDB起動

##2. ソースコード一覧


作成または編集したソースコードは以下の通り。
細かい説明は他のPhoenix系の記事を参照して下さい。
基礎的なことや今回使っている機能は全てそちらに書いてあります。

mix.exs


/web/router.ex


/web/controllers/bbs_controller.ex


/web/view/bbs_view.ex


/web/templates/bbs/bbs.html.eex


実行ページ: http://localhost:4000/bbs
こんな感じの画面が表示されるはず(テストデータあり)


##3. まとめ

作成中に少々の問題は起こったが日数2日間で完成~
(これを遅いと見るか、速いと見るか・・・さてどうだろ・・・)

デザインが残念なのは気にしないで下さい。
CSSは殆ど無知に等しいので(笑)

ソースコード一式は以下のGithubリポジトリにあります。
よかったらどうぞ~
Github: phoenix_bbs

#管理人の独り言~

次は宣言通り、trotをやります。
また、掲示板作るかもしれません。

2015年6月12日

Elixir+Phoenix - InvalidCSRFTokenErrorを対処するだけの簡単なお仕事!

#目的

InvalidCSRFTokenErrorの対処方法を記述する。


#実施環境
OS: Windows8.1
Erlang: Eshell V6.4
Elixir: v1.0.4
Phoenix Framework: v0.13.1

#目次
1. エラー内容について
2. 対処方法について
3. まとめ

#参考文献
http://stackoverflow.com/questions/28595153/phoenix-invalid-csrf-cross-site-forgery-protection-token-error
http://phoenix.thefirehoseproject.com/5.html
https://gist.github.com/chrismccord/cf51346c6636b5052885

#始める前に
昨日、Elixir+Phoenixで掲示板(もどき)を作成していたのですが、
ちょっと、ど嵌まりした実行時エラーがあったので、
アプリケーションは作成途中ですけど記事を上げます。

問題は、HTTPメソッド:Postでページ遷移を行う時に起きた。

##1. エラー内容について

エラー内容は以下の通り・・・
----
(Plug.CSRFProtection.InvalidCSRFTokenError)
Invalid CSRF (Cross Site Forgery Protection) token.
Make sure that all your non-HEAD and non-GET requests
include the csrf_token as part of form params or
as a value in your request's headers with the key 'x-csrf-token'
----

ようは、無効なCSRFのトークンですって言ってる。
そりゃそうだ、設定した覚えないですもの。

CSRFについてはWikipediaを参照すること
クロスサイトリクエストフォージェリ - Wikipedia

##2. 対処方法について
駆逐してやる!エラーなんて一つ残らず駆逐してやる!!

対処方法は2つ(本来は3つだが・・・内容が重複するので)
-1 /web/router.exにある"plug :protect_from_forgery"の設定をなくす。
-2 テンプレートでトークンを設定する。(記述方法が2つある)

まず、一つ目の方法。
/web/router.exを開いて、以下の部分から"plug :protect_from_forgery"を削除。
(コメントアウトでもおk)

※セキュリティの面を見るならあまり良くないと思うけど・・・

----
pipeline :browser do
  plug :accepts, ["html"]
  plug :fetch_session
  plug :fetch_flash
  plug :protect_from_forgery ←これ
end
----

参考: http://hexdocs.pm/phoenix/Phoenix.Controller.html#protect_from_forgery/2

次、二つ目
例えば、/helloと言うページへPostでページ遷移させる時、
以下のように記述すると思う。(ソースは該当部分だけ)

エラーの出る記述
----
<form method="post" action="/hello">
  <input type="submit" value="hello">
----

上記を以下のような記述に変更する。

エラーの出ない記述
----
<form method="post" action="/hello">
  <input type="hidden" name="_csrf_token" value="<%= get_csrf_token() %>">
  <input type="submit" value="hello">
----

やっていることは簡単ですね。
隠しデータで、CSRFのトークンを送っている。

"<%= get_csrf_token() %>"だが、トークンを取得するviewのヘルパー関数を利用している。

/web/web.exのviewの部分でインポートしている。
(ここのview部分に記述するとviewの全てに反映される)

いつのバージョンかは知らないが、get_csrf_token/0の関数がなかったので、
自分でセッションから取得したり、ヘルパー関数自体を自分で定義したりしてたらしい・・・

この記述
----
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
----

また、v0.9(?)、v0.10(?)あたりのアップグレードで
以下のような記述にてCSRFトークンを送れるようになったらしい・・・
(こちらの方がすっきりしてますね!!)

Phoenix的(?)な記述
----
<%= form_tag("/hello", method: :post) %>
  <input type="submit" value="hello">
----

##3. まとめ
意外と嵌ったエラーだった。
そもCSRFって何?とか、どうやって送るの?とか、知識と経験がないからちょっと手こずった。
でも、探せば同じ問題で記事または質問を上げている人が見つかる内容だったので、
そこまで難題でもなかったかな。

ものによっては、ガチで記事皆無とかあるからな~(Elixir+Sheriffとか、Elixir+Sheriffとか・・・)

ちなみに、Railsでもトークンは送っていたはず・・・
そこら辺から切り口にすればもうちょい楽だったかもしれない。

と言うわけで、皆さんも気を付けて下さい~ノシ

#管理人の独り言~
昨日、"Sapporo Beam"に参加しました。
その時に話題の一つとして出ていたのですが、
なんと!Elixirにて、Sinatra風フレームワークがあることを聞きました。
"trot"と言うそうです。

リンク: https://github.com/hexedpackets/trot

掲示板(もどき)の作成終わったら、早速手を出してみようかと思います。

正直な話、私が行うプログラム規模だと、
Phoenixほどのフレームワークはいらないんじゃないかと思うわけです。
なので、そちらにメインのフレームワークを移すかもしれません。(使えれば・・・)

2015年6月10日

ElixirからSheriffを使ってみた・・・かったorz

注意!!未完の記事です!!

#目的

ElixirからSheriffを使ってみた・・・かったorz
本来の目的は、Validationをテストすることであった。

詳しく理由・・・
Phoenix - Guide Overviewもしくは、Qiita - Phoenix Framework(v0.13) 概要の記事の中に、
Cowboyの項目でSheriffは型ベースの動的なValidation...と書いてあった。
そのため、いずれ使用するであろうValidationを一足先にテストすることであった。

その様がこれだよ・・・orz

#構築している環境

OS: Windows8.1
Erlang: Eshell V6.4
Elixir: v1.0.4
Sheriff: バージョン不明 (github)

#目次
1. "mix new"でプロジェクト作成
2. Sheriffを早速!使ってみよう!!
3. だめだったよ・・・調査だ!調査!!
4. やっぱりだめだったよ
5. まとめ

#参考文献
Sheriff README
http://erlang.org/doc/reference_manual/typespec.html
http://elixir-lang.org/docs/v1.0/elixir/Kernel.Typespec.html
http://elixir-lang.org/getting-started/typespecs-and-behaviours.html

#情報提供求む

どなたか情報や知識がおありの方、
記事を読んで、もしかしてこれが原因とか、こうしたらどうだろうかといった考察がおありでしたらコメントして頂けると嬉しいです。

##1. "mix new"でプロジェクト作成

>cd 作業ディレクトリ
>mix new プロジェクト名

私は"elixir_use_sheriff"と命名。以降この名称で記述する。

>cd elixir_use_sheriff
>mix test

異常なし!!

mix.exsは以下の通り編集した。


>mix deps.get

これでプロジェクト作成完了!!

##2. Sheriffを早速!使ってみよう!!

参考にするソースコードは公式のREADME!!
Sheriff README

っと言っても・・・

これと
-type colors() :: blue | red | green | yellow.
これ
sheriff:check(Color, colors)

上記の二行をErlangからElixirコードに変換する・・・だけ。(想定では)

この時、管理人はまだ知らなかったのです。
朝から始めて夜になっても終わらないことを・・・

プロジェクト作成の時生成されているソースコードを編集する。
/lib/elixir_use_sheriff.ex

まずは、このコードを変換する。
-type colors() :: blue | red | green | yellow.

Erlangのドキュメントを見る。
http://erlang.org/doc/reference_manual/typespec.html

続いて、Elixirのドキュメントを見る。
http://elixir-lang.org/docs/v1.0/elixir/Kernel.Typespec.html
ん?Getting Startの方もあった。
http://elixir-lang.org/getting-started/typespecs-and-behaviours.html

ふむふむ、何となく分かった!!(気がする・・・変わらず英語に弱い)

Erlangでは、小文字で始まるものはatomのはず、
また、-typeはそのまま@typeに変換する。

ドキュメント見る限りはこれで問題ないはず・・・
定義場所はモジュールの中に定義する。

とりあえず、こんな感じで変換。
@type colors() :: :blue | :red | :green | :yellow

よっし、じゃあコンパイルしよう!
>mix compile

ん~、エラー出てないし記法的な問題はないっぽいね。
んじゃ、次!!

このコードを変換だ!
sheriff:check(Color, colors)

事前学習はしてきたぜ!!
まずは、適当に関数を作成する。

Erlangのライブラリを使う時は、:(コロン)を付けてモジュールを記述する。
例) :erlang.size("test")

----
def test(color) do
  :sheriff.check(color, colors)
end
----

コンパイル、コンパイル~
>mix compile

ん?エラー出た。

----
** (CompileError) lib/elixir_use_sheriff.ex:5: function colors/0 undefined
    (stdlib) lists.erl:1336: :lists.foreach/2
    (stdlib) erl_eval.erl:657: :erl_eval.do_apply/6
----

undefined・・・定義されてないだと?
ここら辺から段々と雲行きが怪しくなる・・・

##3. だめだったよ・・・調査だ!調査!!

う~む、出てしまったものはどうしようもない。
とりあえず、Erlangのソースコードから関数の動作を予想しよう。

見る限りだとシンプルな内容である。
引数(アリティ)は2つ、checkで検証している。(check/2)

第一引数は、おそらくatomで色を指定するのだろう・・・
第二引数は、検証する時の該当色・・・つまり-typeで一致させる一覧を定義しているのだろう・・・

っと予想した。
とりあえず、べた書きするか・・・
この部分を第二引数に記述する。
:blue | :red | :green | :yellow

っとこうなる。
:sheriff.check(color, :blue | :red | :green | :yellow)

でも、ちょとまてちょとまてお兄さん!
引数二つですよ?しゃーないから、タプルにする。

こうなった。
:sheriff.check(color, {:blue | :red | :green | :yellow})

>mix compile

またエラー?しょうがないな~
何々、|(パイプライン)が定義されていない?
タプルでこの書き方できたっけ?(Elixir力が低いことが露呈し始める・・・)
----
** (CompileError) lib/elixir_use_sheriff.ex:5: function '|'/2 undefined
    (stdlib) lists.erl:1336: :lists.foreach/2
    (stdlib) erl_eval.erl:657: :erl_eval.do_apply/6
----

タプル調べた。,(カンマ)に変えてみる。
:sheriff.check(value, {:blue, :red, :green, :yellow})

おっ!?通った!!
よしこれでテストができる。



mixで取ってきたライブラリも含めてiexで使えるようにする起動オプションでコマンドを叩く。

>iex -S mix
iex(1)> ElixirUseSheriff.test(:blue)
false

動いた!?あれでも待って・・・想定してる動作してないよ!!
(Why!! Elixir Program!!!!)

とりあえず動作はした。でも、想定している動作はしていない。
こいつはどうやら、check/2自体を検証してみるしかないな・・・

##4. やっぱりだめだったよ

再びiexより・・・
>iex -S mix
iex(1)> h(:sheriff.check/2)
:sheriff was not compiled with docs

あ・・・ヘルパー関数でドキュメント見ようと思ったけど、
ドキュメントはコンパイルしてないみたいね。
仕方ない・・・直接幾つかパターンをcheck/2で試してみよう・・・

まずはべた書き・・・
実例1) :sheriff.check(:blue, :blue)
結果: false

実例2) :sheriff.check(1, 1)
結果: false

実例3) :sheriff.check("test", "test")
結果: false

!?
まさかの全部だめ・・・あれ、これやばくね?

次、Elixir Kernel.Typespecのドキュメントに型が記述されていた。
あれを使ってみよう!!
実例1) :sheriff.check(1, Integer)
結果: false

Integerはモジュールだよね・・・

実例2) :sheriff.check(1, integer)
結果: ** (RuntimeError) undefined function: integer/0

エラー・・・

実例3) :sheriff.check(1, :integer)
結果: false

atomを指定してどうするのか・・・
この後、次々と色々なパターンを試してみたが駄目だった・・・

sheriffのソースコードを見てみるも・・・
Erlangレベルが低いため、なんとなくしかやっていることは分からず・・・

自分の頭では限界なので、ネットに解決の糸口がないか探しに旅に出た。
これは!?っと思うものを探し、試行錯誤してみるも空しい結果に終わった・・・

しかも行き着くサイトはほとんど、GithubかStackOverflow、海外サイトである。
英語はもういやだ・・・

そして手詰まり・・・お手上げ・・・もう無理ぽ(´・ω・`)

##5. まとめ
何がいけないのか少し考察してみた。
これって言うのはないが、多分ここら辺調べればいいんじゃね?くらいのレベルだが・・・

・check/2の引数に対しての認識が間違っている?
・check/2関数本体の動作予測が間違っている?
・@typeの使い方間違えているんじゃないか?
・変換したコードだとElixir側では足りないものがある?
・実は根本的に、ElixirでのSheriffの使い方が間違っている?

とりあえず、こんなところかな~
Typeや型に対しての認識、Erlang力、Elixir力が足りないと言うのは分かった。

ElixirでValidationするだけなら他にもライブラリあるし!!!!(涙目・・・)

以上・・・誰か救いの手を下さい・・・

2015年6月9日

ちょっと現状の取りまとめ

#目的: 現在の状況を取りまとめる。

#構築している環境

OS: Windows8.1
Boot2Docker:v1.6.2
TextEditor:Sublime Text Build 3083 x64
Ruby:v2.2.2
Haml:v4.0.6
Erlang: Eshell V6.4
Elixir: v1.0.4
Phoenix Framework: v0.13.1
Sinatra:v1.4.6
Node.js: v0.12.4
MongoDB:mongodb-win32-x86_64-2008plus-ssl-3.0.3-signed
Git:Github、msysGit(msysGit-netinstall-1.9.5-preview20150319)
mongo(gems):v2.0.4
elixir-mongo(hex): v0.5.1

#現在の使用率上位:

1 - Elixir
2 - Phoenix
3 - Erlang

#作成済み

例)
##プロジェクト名(説明)
- 導入予定1
- 導入予定2
...etc

##sinatra_bbs(Ruby+Sinatraによる掲示板・・・もどき)
- Validation
- Modelクラス
- SASS(スタイルシート)
- Padrino導入
- セキュリティ(SQLインジェクション、XSS対策...etc)

#作成予定

例)
##プロジェクト名(説明)

done ##phoenix_bbs(Elixir+Phoenixによる掲示板・・・もどき)
##elixir_twibot(extwitterを利用したtwitterのbot)
##Rails Tutorial for Phoenix(Ruby on Rails TutorialをPhoenixで実施)

#ToDoリスト

基本、上に書いているタスクの方が優先順位が高い。
おそらく、実施して記事にするのも速い。

例)
##項目名
- ToDo名(説明)
- ToDo名(説明)
...etc

##ErlangVM
done - trot(フレームワークを使う)
- elixir_twibot(extwitterを使い、TwitterAPIを利用する)
- elixir_httpoison(httpoisonを利用してidobataのAPIを叩く)
- elixir_cowboy(ElixirからCowboyを利用する)
done- phoenix_bbs(Elixir+Phoenixを利用して掲示板・・・のようなものを作成する)
- erlang記法習得(ElixirからErlangを利用するために、Erlangの記法を取得する)
done- elixir_Sheriff(ElixirからCowboyの組み立て部品の一つであるSheriffを利用する)

##Node.js
- シングルページWebアプリケーション(本を購入したので実践してみる)

##React.js
- 話題のReactを使ってみる(Phoenix、Sinatraどちらでも良いので導入してみる)

##Docker
- data_volume_container(ホストのデータをコンテナから利用できるようにマウントする)

##Sinatra
- sinatra_formkeeper(Sinatraで利用できるValidationの一つ)
- modelクラス導入(DBを利用しやすいようにModelクラスを作成する)
- SASS導入(自作のスタイルシートを導入する)
- Padrino導入(Sinatraを拡張できるフレームワークを導入する)

##MongoDB
- セキュリティ強化(プログラム側へNoSQLに対するインジェクション対策、XSS対策を導入する)

#参考文献
なし

#独り言~
Elixir、Phoenixの日本語記事が少ない。下手すると海外記事でも少ない。
なので、どんどん試していきたい。
とりあえず、動かせれば理解は後から付いてくると思う。
まぁ、飽きっぽい性格なので、色々切り替えながらやっていくと思いますが・・・

基本ToDoリストを作るのは好きじゃないのです。
やることが大量に出てき過ぎるので、モチベーションが下がる。
でも、まとめるために作成した。

もちっと良い方法とか知ってはいるが、すぐにやれるほど習得していない・・・
それって結局使えないと同義だね!!

それにしても今後の予定の記事から大分方向がそれましたな・・・
まぁ、いいけどね。

2015年6月8日

ElixirからErlangの関数を呼び出すだけの簡単なお仕事!!

タイトル: ElixirからErlangの関数を呼び出すだけの簡単なお仕事!!

目的: Elixirのiexから自作したErlangのモジュールで定義している関数を呼び出す。

実施環境:
OS: Windows8.1
Elixir: v1.0.4
Erlang: Eshell v6.4

目次:
1. 概要
2. Erlangのソースコード
3. iexで関数を呼び出すだけの簡単なお仕事
4. おまけ
5. おまけのおまけ

1. 概要
ふと思いました。
ElixirからErlangモジュールで定義した関数を呼び出せないか・・・っと。

同じErlangVMで動いているのですから動かないということはないでしょう。
なので試してみました。

実際、記事にするほどのことではないのかもしれませんが・・・

2. Erlangのソースコード

Erlangのソースコードは以下の通り作成しました。
"test"と言うモジュールにaddと言う関数があるだけです。



3. iexで関数を呼び出すだけの簡単なお仕事

コマンドプロンプトからiexを立ち上げ、以下の通り実施しました。

```iex
>iex
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c("test.erl")
[:test]
iex(2)> :test.add(1, 2)
3
iex(3)>
```

cのヘルパーメソッドを利用してコンパイルしています。
Erlangのファイルが置いてある場所を見れば、"test.beam"ができています。

4. おまけ

逆に、Erlangから自作したElixirモジュールの関数を呼んでみます。

Elixirのソースコードは以下の通り作成しました。
先ほどのErlangのソースコードと内容は同じです。



これをerlから呼んでみます。
まずは、iexからコンパイルします。

```iex
>iex
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c("Test.ex")
[Test]
iex(2)> Test.add(1, 2)
3
iex(3)>
```

cヘルパーメソッドがまた出てきました。
実行すると"Elixir.Test.beam"ができています。

```erl
>erl
Eshell V6.4  (abort with ^G)
1> l('Elixir.Test').
{module,'Elixir.Test'}
2> 'Elixir.Test':add(1, 2).
3
3>
```

5. おまけのおまけ

Elixirソースコードからの呼び出しは存外に簡単でした。
Erlangソースコードの変更はありません。

以下のようにElixir側のソースコードを変更しました。
add関数の中で、Erlangで定義されているadd関数を呼んでいます。
str_size関数の中では、Erlangのsize関数を呼んでいます。



実行結果:
----
iex(1)> Test.size("aaa")
3
iex(2)> Test.size("test")
4
iex(3)> Test.add(1, 1)
2
----

修正!!(2015/06/07-16:52)
@behaviourですが、私が間違って理解している可能性があります。
記事に掲載しているソースコードですが、@behaviourがなくても動作します。(確認済み)
なので、ソースコードに関してはなしの状態で修正しました。
公式ドキュメントを確認してきました。
@behaviourは、公式ドキュメントでは以下の通り書いてあります。

引用
>@behaviour - (notice the British spelling) used for specifying an OTP or user-defined behaviour.

簡単に翻訳すると、
"(括弧内は省略)ユーザー定義の振舞いか,OTPが定義した振舞いか区別する"
っといったことが書かれています。
以下のような時に利用されると思われます。

----
@behaviour Test.Hoge
@behaviour Test.Hoge.Huge
@behaviour Test.Hoge.Foo
----

これで終わり・・・以上!!

独り言~
今回のおかげでヘルパーメソッドの存在を認識しました。
(ヘルパーメソッドを見たければ、iexでhと入力しEnterすれば出てきます)

それにしても・・・こんな簡単にできるんですね!
次は、Elixir+Cowboyあたりで検証してみましょうか。
(需要あるのでしょうか・・・)

参考文献
http://blakewilliams.me/blog/playing-with-elixir-and-erlang
Elixir - Module attributes

2015年6月7日

Phoenix - Channels Guideの実行例を実施

タイトル: PhoenixのChannels Guideの実行例を実施

目的: Phoenix - Channels Guideの実行例を実施する。

実施環境:
OS: Windows8.1
Erlang: Eshell V6.4
Elixir: v1.0.4
Phoenix Framework: v0.13.1
Node.js: v0.12.4

目次:

  1. 概要
  2. 実行例を実施する
  3. 疑問点について

1.概要

1.1
記事を書いた理由。

ちょっと実行例を実施する時に戸惑ったのと、
v0.11.0のソースコードと少し異なる部分があったため。

ソースコードの記述例一式と実行について記事を書きます。

合っているとか妥当とかは置いておくとして。
実行できる!って言うことを優先しています。

1.2
あらかじめ、テスト用のプロジェクトは作成しておいて下さい。

以下、私の実行例
>cd 作業ディレクトリ
>mix phoenix.new phoenix_channels
>y(npm?の使用を聞かれるからyes)
>cd phoenix_channels
>mix phoenix.server
ブラウザからlocalhost:4000にアクセス。

アプリケーション名: phoenix_channels
設定は全てデフォルト

2.実行例を実施する

2.1
ソースコード例の一式~
以下の通り作成した。

/web/router.ex


/web/channels/room_channel.ex


/web/static/js/app.js


/web/templates/page/index.html.eex


/web/templates/layout/application.html.eex


2.2
いつも通りの実行を行う。
>mix phoenix.server

以下のアドレスへアクセスする。
アドレス: http://localhost:4000

ブラウザのタブをもう一つ追加して同じアドレスへアクセスする。

index.html.eexで記述したインプットフォームへ適当に文字を入力し"Enter"を押す。
どちらのタブにも入力内容が表示されれば、動作確認は問題ない。
参考までに画像を貼っておく・・・参考になるかな~・・・

ブラウザタブ1

ブラウザタブ2

Tips
Javascriptのコンソールログを確認すれば、
"Welcome to Phoenix Chat!"と出力されている。

3.疑問点について

3.1
疑問1

"http://localhost:4000"にアクセスしているのに、
チャネルの"/ws"のパスも動いてるは何故?

また、"http://localhost:4000/hello"と言った時の動作は?
これは検証すればいいが一応・・・

追記(2015/06/07-15:54)
解答
application.html.eexには以下の記述があり、app.jsを実行している。

ソースコード抜粋
----
<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
----

app.jsには、以下の記述があり実行されている。

ソースコード抜粋
----
let socket = new Socket("/ws")
socket.connect()
let chan = socket.chan("rooms:lobby", {})
----

つまりべた書きで実行してたわけか・・・そりゃ動きますわ・・・

3.2
疑問2

RoomChannelで"rooms:lobby"とそれ以外の処理を行うjoinコールバック関数を定義している。
"http://localhost:4000"にアクセスした時、
"rooms:lobby"を指定していないのに動作しているのは何故?

デフォルトの設定がなされている?
あるならそれはどうやって設定?ないし処理している?

追記(2015/06/07-15:55)
解答
疑問1での解答より、べた書きで実行しているため。
app.jsに書いてある。

3.3
疑問3

例えば、チャネルのルーティングを二つ作成したとする。
"/ws1"、"/ws2"と言ったパスで。

今回の実行では、
"http://localhost:4000"にアクセスした時、
"/ws"のパスも動いているが、二つ定義している時は、どちらも動くのか?

追記(2015/06/07-15:56)
解答
疑問1での解答より、べた書きで実行しているため、
定義しても動作しないと見受けられる。

っといった疑問点がありますね。
私が調査できてないだけ、読み取れていないだけと言うこともありますが、
この辺りを把握しないと実際のアプリケーションには組み込めないです。

今後の調査で把握できれば、また別記事を上げますね。

追記(2015/06/07-15:58)
全て同じ解答に行き着くという・・・ソースを読めって話ですね~
ようは、HTTPの通信とWebSocketの関係が分かってなかったわけですね・・・この私が!!
WebSocketの説明について参考までに・・・
参考1: https://www.atled.jp/jireinavi/develop/websocket/
参考2: south37のブログ - WebSocketについて調べてみた。

以上!!

参考にさせて頂いたサイト様
Phoenix - Channels Guide
Phoenix Framework - Channel 日本語翻訳

管理人の独り言~
Channel Routesについて別記事を上げてますので、良かった一緒にどうぞ~
続!Phoenixのルーティング(Router)について分かったこと

これにて、Elixir(Phoenix)強化週間中の記事終わり~
今後もElixirはやっていきますが。
今回ので何とか基礎は習得できたかな?
それらを組み合わせて掲示板もどきの作成にでも入りますか~

記事を書いてから気付いた。
"Tying it all together"って書いてあんじゃん・・・おおうorz

自分用メモ・・・
httpの通信は、"http://・・・"
WebSocketの通信は、"ws://・・・"

http://とws://は両立して流せるけど、別の通信ってことか。

しかし、通信の流れを追ってみたが・・・
/wsは追えるが、rooms:lobbyが追えない・・・何でだろう?
httpとWebSokectの通信混じると、私の貧弱な頭では分からないいいいい・・・
参考: http://d.hatena.ne.jp/uuwan/20130121/p1

人気の投稿