2018年9月23日 Elmに入門してみた その1 背景 フロントエンドの技術を何か身に付けたいなぁと考えていた時、Rebuild.fm#214でElmの話をきき良さそうだなと思い軽く触ってみました。 私のスペックとしては、サーバーやゲームのクライアントがかけるエンジニアで、JSは書けるけどReactやVueなどのフレームワークは触ったことがないくらいのレベルです。 また、関数型言語についてもElixirやlispを少し触ったことがあるくらいでそこまでガッツリ触ったことがないというレベルです。 今回は公式のガイドやドキュメントを眺めて得た知識を簡単にまとめます。 その1ということで簡単に、シンタックスなどをまとめます。 環境 私の環境が以下のような構成のため、それを想定した記事となっています。 OSX High Sierra elm 0.19.0 vim 8.1 Elmとは? ElmはJavaScriptにコンパイルできる関数型言語で、Reduxの元になった言語と言われてます。 仮想DOMを標準でサポートしています。 また、Elm Architectureというアーキテクチャを言語レベルで定めているのも面白い一面かなと思います。 インストール Elm brewで一発 $ brew install elm インストールすると以下のツールが手に入ります。 elm repl elm reactor elm init etc… vim elmcast/elm-vimを入れてます。 vim 上で使えるようにするため、フォーマッタなどを入れます。 # vim上でunit testできるようにするやつ $ npm install -g elm-test # コード補完とdocument $ npm install -g elm-oracle # フォーマッタ $ npm install -g elm-format パッケージ管理にはdeinを使っています。適宜読み替えてください。 call dein#add('elmcast/elm-vim') 文法 基本 コメントアウト 2018年9月16日 isucon8予選に参加してきました 9 / 15 の予選1日目の土曜日にチーム名「さばかんちゃーはんかれー」として参加して来ました。 2年前のisucon6にも出場したのですが、今年は本選に参加するぞという意気込みで、5月くらいから過去問解いたり準備を進めていたと思います。 結果としては予選落ちとなってしまいましたが、 限られた時間内で、アプリケーションを高速化させるという非常にエキサイティングな時間を過ごすことができました。 楽しい問題とリッチなダッシュボード等すごく恵まれた環境下でできたなぁと、運営の方々には感謝しかないです。 運営の皆様ありがとうございました。 また、おなじチームで参戦してくださったお二方(@peto_tn, @matsukaz) ありがとうございました。 そして、参加された皆様おつかれさまでしたー。 ざっくりタイムライン 自分が観測できた範囲をざっくりと。 実際にはもうちょっとミドルウェアのチューニングとか行ってます。 時間 やったこと 10:00 レギュレーション読み 10:10 参考実装をGoに変えてベンチ. たしか1000点ちょっとオーバーくらい. ソースをgithub管理にしたり、アプリをぽちぽちして仕様把握 10:30 profile系をガツガツ入れてく ひたすらソースコードリーディング 15:50 getEventをリファクタしスコアが一気に3万点近くまで上がりみんな盛り上がる。わいわい 16:20 H2Oからapp1, app2をラウンドロピンで実装.DBサーバーの構成に変更 17:00 ベンチがFailしはじめ原因調査 18:00 ベンチがFailする問題をを完全に対処しきれず、原因が特定できないまま、appの実装を戻してFinish. 一時は上位の順位争いに加われてわいわいした空気になってました。 わいわい わいわいしてた時のスクショ 自分やったこともうちょっと詳しく sheetsテーブルをコードで置き換える sheetsテーブルは以下のようなデータ構造でした。 id rank num price 1 S 1 5000 2 S 2 5000 ・・・ 50 S 50 5000 51 A 1 3000 52 A 2 3000 ・・・ はじめ、sheetsテーブルにあるDBのレコードを全て 2018年9月9日 DIPを意識してgoを書いてみる 背景 go言語を触っていて、DuckTypingによるインターフェースとDIPとの相性がかなり良いものだなぁ感じ試して見た記事です。 以前のアーキテクチャについての記事にも書きましたが、ソフトウェアの詳細にビジネスロジックが依存しない方が好ましく、 できれば実装の詳細についての判断をできるだけ遅くすることがアーキテクトの腕の見せ所と言えます。 そこで今回は以下のユースケースをDBに依存することなく実装を進めて見たいと思います。 ユーザー一覧の表示 ユーザーの登録 ソースコードはこちら(http://github.com/foresta/go-dip-sample) DIPとは SOLIDの原則と言われるクラス設計の原則の中の一つで、日本語だと依存関係逆転の原則と言います。 ソースコード 全体のファイル構成はこんな感じです。 src/ ├── memory │ └── user_repository.go ├── mysql │ └── user_repository.go ├── server.go └── user ├── user.go └── user_repository.go パッケージは user, memory, mysql の三つで user がソフトウェアドメインに関するパッケージ、 memory, mysqlはデータストア (インフラ) に関するパッケージです。 今回はmysqlを準備することなくメモリ上にユーザーデータを保存をできるようにします。 ユーザーは以下のようなデータ構造とします。 // user.go package main type User struct { ID int Name string Email string } 保存にはUserRepositoryというインターフェースを使用することにします. // user_repository.go package user type Repository interface { Store(u *User) error FindAll() []*User } 以下にmainパッケージの処理全てを載せます。\ 2018年9月2日 書籍「Clean Architecture」を読んだまとめ 普段からソフトウェアの設計やアーキテクチャに関心があり色々調べていたのですが、 最近発売された、「Clean Architecture」がとても良さそうなので読みました。 結果すごく良かったのでエッセンスをまとめます。 書籍「Clean Architecture」 Clean Architecture 達人に学ぶソフトウェア構造と設計 この本は、「ソフトウェアの価値とはなんなのか」という着眼点から始まり、プログラミングのパラダイムに軽く触れたのちに、アーキテクチャの話に深く入っていきます。 題名から、いわゆる設計手法としての「Clean Architecture」についての話かと思いがちですが 内容はアーキテクチャとは何か、どういった目的意識があるのかいうアーキテクチャ全体的な概念などの非常にためになる話が多くいくつも気づきがありました。 以下、簡単にまとめます。 ソフトウェアの価値とは ソフトウェアの価値は、「提供する機能」と「更新できること」にあります。 「提供する機能」とはそのままの意味で、そのソフトウェアが問題を解決することに価値があるということです。 「更新できること」は需要や周りの環境の変化に応じてソフトウェアが変化できること自体に価値があるということです。 ソフトウェアの「ソフト」とは柔軟に変化できることを表していて、継続的に更新できることは大きな価値になり得ます。 アーキテクチャとオブジェクト指向 アーキテクチャの目的とは、ソフトウェア継続的に更新し続けられる柔軟な状態にすることにあると言えるでしょう。 このため、変更が頻繁に起きるところと少ない箇所を分離しお互いが影響しないように適切にソフトウェアの境界を引いて行くことが重要です。 またソフトウェアには「方針」と「詳細」があるという風に言われています。 方針はソフトウェアがどのように問題を解決するかの方針、つまりはビジネスロジックのことを指します。 詳細とはデータベースや、フレームワーク、UIなどのことを指します。 この二つのうち、変更が頻繁に起こるのは「詳細」の方だと思います。 ソフトウェアの目的は「方針」側にあります。 (データベースの種類や、どのフレームワークを使用するかなどの詳細はソフトウェアの本質ではないということ) この「方針」が「詳細」の変更に影響されないように(詳細に依存しないように)依存関係を管理することがアーキテクトの腕の見せ所です。 依存関係を完全に管理するためには、オブジェクト指向プログラミング (以下OOP) のパラダイムが非常に役に立ちます。 OOPの特徴であるポリモーフィズムにより、オブジェクト (あるいはコンポーネント) 同士の依存の方向を制御することができます。 具体的には、SOLIDの原則のDIP (依存関係逆転の法則) で依存の方向を逆転させることで、方針が詳細に依存しないようにして行くことができます。 ちなみに、SOLIDの原則については以下の本に非常に詳しく書かれています。 アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技 私もこの本に出会うまでは、SOLIDの原則について全く知りませんでした。 非常に分厚く読み応えがすごいですが、今ではプログラミングをする上の指針となる大事な原則を得られ、読んで良かったと思える一冊です。 話を戻しまして、書籍「Clean Architecture」には、ソフトウェアのどこに境界を引くのか、依存関係をどうやって管理するのか、についての具体的なエッセンスが多く書かれていました。 ここでは詳細には触れませんが、どのようにコンポーネントを分離するのかや、設計手法であるクリーンアーキテクチャの紹介などが印象的でした。 アーキテクチャの概念等の抽象的な話題から、実際にどうアーキテクチャを考えて行くかの指標になる具体的な話題まで揃っていて非常にお得感のある本でした。 感想 最初にこの本を読もうと思ったのが、kindle版の無料サンプルで公開されている以下の文を読んでこれは面白そうだぞっと感じたのがきっかけです。 崩壊したコードを書くほうがクリーンなコードを書くよりも常に遅い Robert C.Martin; 角 征典; 高木 正弘. Clean Architecture 達人に学ぶソフトウェアの構造と設計 (アスキードワンゴ) (Kindle の位置No.460). 株式会社ドワンゴ. Kindle 版. 他には、 2018年8月31日 週一ブログチャレンジ宣言 自分を追い込んで行くために宣言します。 週一ブログチャレンジ宣言とは 週一でブログを更新するという強制的なOutputの習慣をつくり、InputとOutputのサイクルを回し、より深い知識を得ようとする試みのことです。 モチベーション 私はエンジニアとして働かせてもらっていますが、周囲の優秀なエンジニアと自分を比較して劣等感に苛まれることが多々あります。 そこで優秀だと思うエンジニアと自分の決定的な違いは何なのか?また、どんなとき優秀だなぁと思うのか? という疑問が生まれてきました。 まず、圧倒的に自分にはOutputの量が足りないなぁということ。そして優秀だと感じる瞬間は (当たり前ではありますが) Outputした瞬間であることであると考えました。 まずはOutputの習慣を作ること。そして、Output駆動でより多く深いInputを得ることを目的として週一でブログを更新していこうと思い至りました。 ルール 自分の中で以下のルールを定めました。 ブログを毎週1記事以上書いて公開する 書いたブログはTwitter等でシェアする 締め切りは毎週日曜日23:59まで (終わるまで寝れない) ブログの内容は問わない 4番目に関しては、内容は問いませんがあくまで「InputとOutputのサイクルを回す」「深い知識を得る」という目的に沿っていればOKという前提はあります。 意気込み 頑張るぞ! (これ続かなかったらすごく恥ずかしい結果になりそうだなぁ……) 2018年8月2日 Planckキーボードを作ってみた 2018年4月15日 Hugoで作成したブログをPWA対応した(ホーム画面に追加のみ) 背景 PWA(Progressive Web Apps)自体は以前から気にはなっていたのですが、最近iOS11.3のSafari11.1から対応されるとのことで周囲でちょっと盛り上がってたので自分のブログに対応させてみたくなってしまったので対応させました。 今回説明するのはホームスクリーンにアイコンを設置できるようにするところまでです。 前提 公式サイトによるとバナーが出る条件は以下のようになっています。 * 次の情報が記述されたウェブアプリ マニフェスト ファイルが存在する。 - short_name(ホーム画面で使用) - name(バナーで使用) - 192x192 の png アイコン(アイコンの宣言には MIME タイプ image/png の指定が必要) - 読み込み先の start_url * サイトに Service Worker が登録されている。 * HTTPS 経由で配信されている(Service Worker を使用するための要件)。 * 2 回以上のアクセスがあり、そのアクセスに 5 分以上の間隔がある。 対象のWebサイトのhttps対応が必須なので やられてない方はLet’s Encryptなどを用いてhttps対応してください。 (手間みそですが、さくらVPSに導入する記事です。https://qiita.com/kz_morita/items/ba9c171633ca54d72d2a) やったこと https対応はすでにしているので今回やらなきゃいけないことは以下の二つです。 manifestファイルの用意 ServiceWorkerの登録 順に説明していきます。 manifest.jsonの作成 以下のようなjsonファイルを作成しました。 { "icons": [ { "src": "images/logo/logo-512.png", "sizes": "512x512", "type": "image/png" }, { "src": "images/logo/logo-256.png", "sizes": "256x256", "type": "image/png" }, { "src": "images/logo/logo-192. 2017年12月2日 Elixirで線形回帰してみた この記事はElixir Advent Calendar 2017の17日目の記事です。 最近始めたElixirで何かOutputしたいということで線形回帰のアルゴリズムを実装してみました。 リポジトリはこちら https://github.com/foresta/mlex.git Elixirでも機械学習できないこともない(かもしれない)ことを書いていこうかなと思います。 背景 最近の私の興味があるものとしてEilxirと機械学習があります。 Elixirはサンプルアプリや簡単なツールを制作した程度、機械学習はcourseraのコースを一通りやり本を数冊読んだ程度です。 今回はその両方の学習と、どうせ機会学習アルゴリズム実装するなら書きごごちの良いElixirで書いてみたいと思い実装してみました。 線形回帰とは データを元に線形モデルを作成しその線形モデルを用いて未知のデータを予測するものです。 図1はデータの次元が2次元の場合の線形回帰の概念を示し、×印が与えられたデータ、直線が学習した結果の線形モデルを表しています。 図1 線形回帰のサンプルグラフ 詳しくはこちらのサイトを参照してください。 https://qiita.com/ynakayama/items/5732f0631c860d4b5d8b http://gihyo.jp/dev/serial/01/machine-learning/0008 学習データ 今回学習には以下のデータセットを使用しました。 linnerud_physiological.csv linnerud_exercise.scv linnerud_physiological.csvには体重・ウエスト・心拍数等の身体的特徴データが、 linnerud_exercise.csvには懸垂・腹筋・跳躍に関するデータがあります。 今回は身体的特徴と、懸垂のデータで線形回帰をしてみます。 実装 使用したライブラリは以下のような感じです。 defp deps do [ {:matrix, "~> 0.3.0"}, {:csv, "~> 2.0.0"}, {:explotter, git: "https://github.com/foresta/explotter.git"} ] end ソースコードは以下のような感じです。 mlex/apps/sample/lib/linnerud.ex def run do # 1. load dataset features = load_linnerud_feature_dataset() targets = load_linnerud_target_dataset() # 2. setup featuresex pulses = features[:pulse] waists = features[:waist] weights = features[:weight] number_of_data = length pulses bias = for _times <- 1. 2017年9月26日 courseraの機械学習コースを完了した 概要 先日courseraの機械学習コースを修了しました。 期間としては, 6月末くらいから始めて9/23に終えたので大体90日くらいかかりました。 (全部で11週分のコースがあるため、順調にすすめば11×7で77日くらいには終えられそうです) 終えた感想としては最高で、終えた他の人たちが口々に「とりあえず、courseraのmachine-learningコースやっとけ」って言ってる理由がはっきりわかりました。 控えめに言って最高でした。 学んだこと ひたすら列挙していきます。 機械学習基礎 教師ありと教師なし学習 分類問題と回帰問題 教師あり学習 線形回帰(単回帰、重回帰) ロジスティック回帰 ニューラルネットワーク SVM 教師なし学習 K-means PCA 異常検知 レコメンドシステム large scale machine learning bias/variance 正規化(regularizatoin) 学習曲線 エラー分析 ceiling analysis 私のバックグラウンド 大学で線形代数・微分方程式などやっていたが、はるか彼方の記憶となっている アプリエンジニアとして、プログラミングしている(C++) 機械学習に関しては何も知らない 事前準備 これの0章,1章,2章をさらっとやりました。 プログラミングのための線形代数線形代数は大学の講義でもやっていたため、復習の意味と行列を見て吐き気がしないために慣れさせることが目的でした。 良かった点 個人的に最高だった点をあげるなら次のような感じです。 授業がわかりやすい 総じて説明もスライドもわかりやすかったです。 特に良かったのがAndrewさんが実際に機械学習プロジェクトに関わっていた時の知見とか、実装上のポイントが多く説明されていて、ここら辺はすごく役に立ちそうだなと思いました。 課題とクイズと締め切り 一定のまとまりの単位でクイズと課題、そしてその締め切りが用意されています。 クイズはちゃんと講義を理解していないととけないしかといって難しすぎもしない良い感じでした。 課題は実際にoctaveという言語を用いて行うのですが、頭で理解していても実際に手を動かすと分からなかったりすることが多々あり、 これは良い仕組みだなぁと感じました。 修了証がもらえる(有償) スタンフォード大学の公式の修了証がもらえるのはかなり嬉しいですね。 Andrewさんのエモいお言葉が聞ける コースの最後にまとめと謝辞的なものがあるのですが、これが個人的にはとても心に響いてすごいこのコースをとって良かったと思いましたので、まだ受講されていない方は、ぜひ最後までやってみてください。 困った点 日本語字幕が時々役に立たない まぁこれは本当に強いて言うならって感じなのですが、 英語力が全くない自分にとっては英語字幕がないと大変なこともありました。 2017年7月7日 alfred上でshellを実行する 日頃開発をしていて、面倒な作業をshellにするのはよくやられていることだと思うが、 毎回ターミナルから実行するのがちょっと面倒だった。 自分はalfredというランチャーソフトをつかっていて、Alt + Spaceで簡単によびだせる設定にしているので、ここからshellを実行できないもんかなーと思って調べてみたらできたのでまとめてみる。 環境 OS X El Capitan Alfred 1.2 方法 任意のシェルを作成する(hoge.sh)とする 実行権限をつける hoge.shをhoge.appにリネーム alfredから実行 これだけ。 シェルを作成しただけだと以下のようになって実行はできない。 がリネームするとこうなる。 ためしにデスクトップ通知をするだけのshellを書いてみる。 hoge.sh #!/bin/bash↲ if [ "$(uname)" == 'Darwin' ]; then↲ # デスクトップ通知↲ osascript -e 'display notification "hogehoge" with title "title"'↲ fi↲ これを実行すると次のようにちゃんと実行できる。 これは色々とはかどりそうで良いぞ。 こういうのでどんどん開発効率を上げていきたいですね。 2017年6月27日 Cocos2d-xで並列に通信をする 先に結論 シーケンシャルに通信するときは HttpClient::send(HttpRequest* request); パラレルに通信するときは HttpClient::sendImmediate(HttpRequest* request) を使用すれば良さそう。 背景 アプリケーションが画像などのアセットを取得するときに、1件ずつシーケンシャルにダウンロードするのではなく並列に通信したかった。 結論までの経緯 まず内部実装をみてみる。 それっぽいのがHttpClient::sendクラスだったのでその実装を見ていく。 //Add a get task to queue void HttpClient::send(HttpRequest* request) { if (false == lazyInitThreadSemphore()) { return; } if (!request) { return; } request->retain(); _requestQueueMutex.lock(); _requestQueue.pushBack(request); _requestQueueMutex.unlock(); // Notify thread start to work _sleepCondition.notify_one(); } 詳しくは見ないが、_requestQueueにリクエストを詰めているだけのようだ。 その_requestQueueはどこ使われているかというと 同じくHttpClientクラスのnetworkThread()で使用されていた。 // Worker thread void HttpClient::networkThread() { increaseThreadCount(); while (true) { HttpRequest *request; { std::lock_guard<std::mutex> lock(_requestQueueMutex); while (_requestQueue.empty()) { _sleepCondition.wait(_requestQueueMutex); } request = _requestQueue. 2017年6月21日 jenkinsさんが503 Service Unavailableと言ってるのを修正したメモ Jenkinsさんが動かなくなってしまったので対応したメモ 借りているさくらVPSのCentOS6.7で軽い気持ちで $ sudo yum update したらJenkinsが動かなくなってしまった。 具体的には503が返ってきてしまう。 とりあえず、原因を調査するためにlogを見てみる。 自分の環境では以下にある。 $ /var/log/jenkins ログの中には以下のような記述が。 ・・・ Jenkins requires Java7 or later, but you are running 1.7.0_79-b15 from /usr/java/jdk1.7.0_79/jre java.lang.UnsupportedClassVersionError: winstone/Launcher : Unsupported major.minor version 52.0 ・・・ Javaのバージョンによるエラーっぽかったので公式サイトを見てみる。 すると以下のissueがたってた https://issues.jenkins-ci.org/browse/JENKINS-43492 yum updateでJenkinsがアップデートされ、Java8が必須になったみたいなので対応していく。 Javaインストールが必要な場合は以下の記事が参考になると思う。 http://qiita.com/Sa2/items/8ba501294df745be8c78 自分の環境だと、すでにJava8はインストール済みだったのでalternativesでjavaのバージョンを変更する $ sudo alternatives --config java alternatives結果 このdefaultがjava8だったのでこれを使用するように変更したのちに、Jenkinsを再起動したら無事動きました。 よかったよかった。 参考にしたサイト様 http://blog.officekoma.co.jp/2017/04/jenkins-http-error-503-service.html 2017年6月13日 CentOS6系のyum updateでつまづいたのでメモ 背景 let’s encryptの証明書更新用に仕込んだcronがエラーを吐いているようで、 原因を調査したところyum install系で更新ができないエラー。 yum updateすればなおるかなーと思ったがそもそもyum updateも404返ってきてうまくいかない。 どうやら、yumのリポジトリのミラーが古いバージョンのままになったようでした。 環境 さくらVPS CentOS 6.7 解決方法 以下のサイトが非常に参考になったので、その通り下記の対応をしたら無事に解決した。 よかったよかった。 [tips][Linux]旧バージョンCentOSでyum更新できなくなった時 $ su - $ cd /etc/yum.repos.d $ cp -p CentOS-Base.repo CentOS-Base.repo_yymmdd $ sed -i -e "s|mirror\.centos\.org/centos/\$releasever|vault\.centos\.org/6.7|g" /etc/yum.repos.d/CentOS-Base.repo $ sed -i -e "s|#baseurl=|baseurl=|g" CentOS-Base.repo $ sed -i -e "s|mirrorlist=|#mirrorlist=|g" CentOS-Base.repo $ cp -p CentOS-SCL.repo CentOS-SCL.repo_yymmdd $ sed -i -e "s|mirror\.centos\.org/centos/\$releasever|vault\.centos\.org/6.7|g" /etc/yum.repos.d/CentOS-SCL.repo $ sed -i -e "s|#baseurl=|baseurl=|g" CentOS-SCL.repo $ sed -i -e "s|mirrorlist=|#mirrorlist=|g" CentOS-SCL. 2017年6月5日 DDD本を読んだのでメモ 導入〜第1章まで 前から読みたかったDDD本を、読み始めたので雑にメモしていく。 ドメインとは、そのシステムが解決したい問題の領域のこと。 DDDにおいてのモデルとは、以下のようなもの 設計と相互に形成し合う チームメンバが使用する言語の基盤 蒸留された知識 設計と相互に形成し合う これはDDDがモデル駆動開発で進められることを意味している。 設計時にモデルを書きそこからコードを書き始める。 また逆に、コードを書き始めて気づいたことなどをモデル側にも反映させることでモデルとコードを一緒に成長させていく。 チームメンバが使用する言語の基礎 これは後ほど出てくるユビキタス言語について。 チームメンバ同士がコミュニケーションする際には、モデルや実際にコード上で表現されている言葉を用いる(逆にコミュニケーションに用いられる言葉をコードに落とし込む) 蒸留された知識 モデルはドメインの知識をそのまま反映したものであるべき。 モデルと実装が紐付いていれば、コードから得た知見をモデルに反映できる。 そうして、どんどん知識は噛み砕かれてよりドメインを明確に表すものに蒸留されていく。 これらの設計を進めていくためには、ドメインの知識を噛み砕く必要がある 第1章 知識を噛み砕く ドメインエキスパートの頭の中にあったり、過去のシステムなどからドメインに関する知識を得ることが重要で、繰り返し継続的にドメインに関する知識を学習する必要がある。 得た知識の中から重要な概念を抽出し、それをそのままコードに落とし込む。 オブジェクト指向でよく言われる、名詞を抽出するという手法の他に、 ビジネスルールなども概念として抽出する。 ビジネスルールなどはよくif文の中などに現れる。 例えばATMでお金を引き出せる時間かどうかのロジックについて考えると、 以下のように書かれることがある。(適当な疑似コード) Time now = Time::Now(); Time am9 = Time(9,0,0); Time pm10 = Time(22,0,0): if (am9 < time && time < pm10) { // 引き落とし処理 } このようにしてしまうと、処理の中に重要な業務ルール(引き落とし可能時間) が隠れてしまう。 そこでPolicyクラスなどを作成すると良いとされている。 if (businessHourPolicy.isAllowed(Time::Now())) { // 引き落とし処理 } ただしこのような手の込んだ設計はどこにでも適用することは推奨されていない。 ドメインの中でも特に重要となる知識に対して行うことが重要。 このようにして書かれたコードはドメインエキスパート(非エンジニア)にもコードを見せることができ、プログラマの手助けがあれば理解することができる(はず)。 また、コードを書いたことによる気づきなどをモデルにフィードバックさせ、知識を深めていく。 深いモデル アプリケーションが解決しようとしている問題の核心を表すうまいモデルのこと。 深いモデルを見つけるために、開発を続け、ドメインの知識について継続的に学習・嚙み砕きを行うことが重要とされる。 雑なまとめ DDDはモデル駆動開発 モデルをコミュニケーションに活用する より深いモデルのためにドメイン知識の嚙み砕きを継続的に行う 2016年12月19日 OptionParserのソースコードを読む この記事はElixir (その 2)と Phoenix Advent Calendar 2016 の 1 9日目の記事です。 背景 書籍「プログラミング Elixir」の 13 章でお世話になった OptionParser がとても便利そうだったので、中身の理解と Elixir のソースコードに慣れる目的で、ソースコードを読んでみました。 メインである parse/2 を中心に説明します。 下記に記載するソースコードは全て、公式のものを引用しています。 環境 Elixir 1.3.3 ドキュメント ソースコード おおまかな流れ parse/2 (外部に公開するインターフェース) do_parse/6 (実際にパースの再帰処理を行っているところ) next/4 (パース処理) ソースコード parse/2 まずはメインの parse/2 です。 parse/2 @spec parse(argv, options) :: {parsed, argv, errors} def parse(argv, opts \\ []) when is_list(argv) and is_list(opts) do do_parse(argv, compile_config(opts), [], [], [], true) end 引数の opts をcomple_config/1を通して加工してdo_parseに渡しています。 また、do_parse/6の結果をそのまま返しています。 2015年8月12日 Homesteadに複数サイトを追加する二つの方法 2015年7月15日 Homesteadを使ってLaravel5を動かしてみる 2015年2月10日 UDPについてまとめてみた WebRTCにも使われているプロトコルであるUDPについてまとめてみました。 UDPとは UDP(User Datagram Protocol)とは、TCPと同じトランスポート層のプロトコルです。 RFC768によって策定されています。UDPの特徴として以下のようなものがあげられます。 コネクションレスなデータ通信 データの信頼性、順序などを保証しない 高いスループット(伝送速度) マルチキャスト、ブロードキャスト コネクションレスとは、通信相手との接続を確立しないということです。 送信側が送りたいデータを一方的に受信側に送るため、接続を確立せずに通信が行えます。 こういった特徴があるため、データの信頼性、順序性などは保証されませんが、高速な送信を実現できます。 また、TCPは接続を確立するため、ユニキャスト(1対1)しか行えませんが、UDPはコネクションレスのため、マルチキャスト、ブロードキャストに対応可能です。 その他に、TCPでは複雑な制御をするためにTCPヘッダを送りたいデータに付属させる必要があります。TCPヘッダのサイズは通常20 Byteほどです。UDPにもヘッダは必要なのですが8 Byteと少量のため、小規模なデータの送信などはUDPの方が効率よく行えます。 使用されているサービス UDPプロトコルは以下のような技術に使用されています。 DNS DHCP VoIP 動画ストリーミング DNSはIPアドレスとドメインを対応づけるプロトコルです。 DHCPはLAN内のパソコンなどにIPアドレスを動的に割り当てるプロトコルです。 VoIPはIPネットワーク上で音声データを通信する技術です。 ブロードキャストを行う必要があったり、信頼性よりもリアルタイム性が重要視される場面ではUDPが選択されることが多いです。 データグラム TCPではデータの通信の単位をパケットと呼びますがUDPでは「データグラム」といいます。 実際にネットワーク上を流れているデータは以下のようなものとなります。 UDPデータグラム UDPデータグラムの表 上の表の送信元ポート、送信先ポート、データグラム長、チェックサムまでがUDPヘッダとなり、 ペイロードが実際に送信したいデータになります。 0~15bitまでは16bitが送信元のポート番号を表します。 16~31bitまでは16bitが送信先のポート番号を表します。 32~47bitまではデータグラム長を表します。データグラム長は、UDPヘッダとUDPペイロードの合計値です。 48~64bitまではチェックサムを表します。チェックサムは、データ(ペイロード)の整合性の検査用データとなります。 それ以降がペイロードです。 UDPデータグラムのサイズですが、これはIPパケットのサイズに依存します。 IPパケットは65535 Byteの容量となり、IPヘッダが20 Byteのため、UDPデータグラムで使用可能な容量は65535 – 20 = 63315となります。そしてUDPヘッダが8Byteのため、UDPペイロードの容量は最大で65507 Byteということになります。 よってデータグラム長に入る値は8 ~ 65515ということになります。 まとめ UDPはコネクションレスの通信方法 信頼性を犠牲にして高スループットな通信を実現 ヘッダサイズが小さく、オーバーヘッドが少ない(複雑な制御を行わないため) 2015年2月8日 WebRTC Conference Japanに行ってきました(2日目) 2015年2月5日 WebRTC Conferrnce JAPANに行ってきました(1日目) 2015年2月1日 Swift初心者向け勉強会に行ってきました 2015年1月29日 coocs2d-xでの座標系について cocos2d-xの座標系でつまずいたのでメモ。 タッチイベントを取得する際に,getLocationInViewで判定していたらどうも思い通りの挙動にならない現象が起きてた。 具体的にはy座標が反転してしまうようだった。 結論からいうと、getLocationInViewでなく、getLocationを用いれば左下からの座標で取得できた。 調べると、基本的にcocos2d-xで用いられているのは、OpenGL座標系で「左下」が原点らしい。 cocos2d-xのリファレンスをみると、座標系を取得するメソッドとして、TouchクラスのgetLocationとgetLocationInViewがある。 (以下リファレンスから引用) Point getLocation() const returns the current touch location in OpenGL coordinates. Point getLocationInView() const returns the current touch location in screen coordinates. なるほど。座標系の違いでメソッドが分かれているのか。 やっぱりリファレンスちゃんと見なきゃだめだなと思いました。