Laravelアプリはお手軽にscale outしないので注意が必要

Laravel で Form を利用して、エラーだった場合にそれをどう返すかのサンプルコードは 4.2 でも 5.6 でも以下のように

redirect で返すようになっている。

そして Form を組み立てる View 側では Input::old() を使うとよいということになっている。さっき入力していたデータを復元してあげないと不親切だからだ。

しかしこの組み合わせはクセモノ。

何が起きるかというと Session データに Form の Input すべてを載せることになるので、実質 Session Driver に Cookie は利用できない1。つまり、アプリケーションサーバだけでカジュアルに scale out することはできないということになる。

Session Driver はすべてバックエンドのストレージ前提になり、DBMS や memcached, Redis などが必要になる2。これらの準備が簡単なよくできた PaaS を使っているならよいが、そうでないならインフラの知識も必要になってしまうので、注意しておいた方がよさそうだ。

しかし、この Form の error を redirect で返す方法って Laravel のこのコードで初めて見たんだけど、こういう設計って推奨されるんですかねえ…?

  1. Input がどんな大きさになるのかはよほど注意深く作らないとコントロールできないだろう 

  2. 当たり前だが file は scale out しない。てゆーか DBMS に Session データを置くのも scale out しないような? 

Flowtypeを試してみた

背景

JavaScript はオブジェクトの構造とかコンパクトでプラットフォーム非依存な仕様など、面白いと思う反面、

'' < 1

が true になってしまうなど割とつらい仕様もあるので、大々的には入れたくないなぁと以前から感じていたのですが、ここ数年は JavaScript に型を入れるというのは AngularJS 2 の TypeScript 採用、Facebook の Flow など話題だし、ES2015 にはなんとかえっちらおっちら追いつけそうなので、いっちょ Flow でも試してみることにしました。

※ 私は Ruby を使っていますが、Ruby の場合は型が欲しいと思うことはありませんでした。Ruby にも静的型はないじゃないかと思うかもしれませんが、上のような謎挙動はないので、全然意味が違うということは添えておきたいと思います。

実際のところは直接書いたコードではなく簡易DSLのようなナニカで上の '' < 1 を踏み抜いてしまったことにより型の必要性を感じているので、これを入れればすぐ問題は解決、というわけにはいきませんが、興味が湧いちゃったのでまずはこれをやってみましょう。

判断基準

なぜ Flow なのか。以下を読むべし。

型なき世界のためのflowtype入門 - Qiita

このエントリでは条件が整えば TypeScipt でよい、という判断ですが、自分の場合は、ここ何年かの JavaScript の情勢や ES のリリース方針を見ると、本流である Ecmascript が常に漸進的に更新されていくことがもはや明確であり、正直言うと本家以外の ES の亜流には手を出したくないというのが本音であり、TypeScript も MS がいつまで本気でやるかも分からないという一抹の不安はやはり残っています。1

その点 Flow は type 情報を strip すればただの Ecmascript というところが安心。いま欲しい何かを満たしつつ言語仕様そのものは標準を維持できるので長期的に見てもメリットが大きいと思います。2

Flow: A Static Type Checker for JavaScript

ということで Flowtype 行ってみよー。

準備

すでに babel, eslint は使えているものとします。

$ yarn add --dev \
 babel-eslint \
 babel-preset-flow \
 babel-plugin-transform-class-properties \
 eslint-plugin-flowtype \
 flow-bin

以下、追加変更する設定ファイルの部分。

..eslintrc.json

{
  "parser": "babel-eslint"
}

type の書かれたコードは通常の Ecmascript とは異なるので、eslint の parser を babel を通したものにします。

package.json

"scripts": {
  "flow": "flow check",
  "flow-stop": "flow stop"
}

..babelrc

{
  "plugins": ["transform-class-properties"],
  "presets": ["flow"]
}

で、babel を通すと flow な preset が適用され、余計な情報はカットされます。

yarn flow -- init

として .flowconfig を以下のような感じにしてみました。

[ignore]
.*/doc/.*
.*/dist/.*
.*/node_modules/.*

[include]

[libs]

[options]
log.file=flow.log

[lints]

ほとんど何も設定してません!

気づかなかったけど気をつけた方がよいこと

flow は daemon として動く。そしてそのまま居座る。

0.49.1 で試し直したら終了した時点でプロセスが消えたので、これが正しい動作なのかもしれません!!

やってみた

@flow

コメントに @flow を書くと有効というか検査対象になります。どこでもよいわけではないようで、できるだけ1行目に書いた方がよさそうです。

// @flow

でも

/* @flow */

でも

/**
 * @flow
 */

でもいいけど、とにかくいちばん上に置くのが肝要なようです。

ちなみに、いちいち @flow を書くのが面倒な場合は

flow check --all

とすればよいようです。ただし、テストコードでこれが有効になると割と面倒なことになりそうです。

型を書かなくても error になる

console.log('' < 1)
            ^^ string. This type cannot be compared to
console.log('' < 1)
                 ^ number

リテラルを解釈して型が違うものを比較している場合にはそりゃーダメだよと教えてくれます。いきなり便利!

引数に型を書く

基本的には変数名の後ろに :<type> を付ける形。イマドキこの形が多いと聞いたような? でもよく分かっていない。

function foo(abc :string) {}

と type 情報を付けておくと、

foo(1)

呼び出しが書かれている場合、flow を実行すると以下のように怒られます。

: foo(1)
      ^ number. This type is incompatible with the expected param type of
: function foo(abc :string) {}
                    ^^^^^^ string

おおおお。これが自分的にはいちばん嬉しいかも。

戻り値に型を書く

function foo() :string {}

となっていたら number を返そうとしてると怒られるわけですな。

ローカル変数に型を書く

var foo :string = 1

var foo :string = 1
                  ^ number. This type is incompatible with
var foo :string = 1
         ^^^^^^ string

みたいに怒られますが、この例のように書いてしまうことはまずないだろうし、何かの設計をミスって長寿命な変数を使ってしまった場合に有効なのかな?

プロパティに型を書く

これがドキュメントを見渡しても分からず、

this.foo :string = 1

と書いてみたところ

this.foo :string = 1
         ^ Unexpected token :

型のチェックではなく文法的にアウトという表示になってしまう。これの正解は上でしなっとインストールしてあった

Class properties transform &#183; Babel

を使って

class Foo {
  bar :string = 1
}

のような形で書くことで解決です。

フィールド定義は 2017-07 時点では Stage 2 ( Draft )

今回利用した機能は 2017-07 時点で Stage 2 ( Draft ) の内容らしく、ES2015 の範囲外の機能となる

tc39/proposal-class-fields: Orthogonally-informed combination of public and private fields proposals

の Field declarations に書かれている内容になります。要は

class Foo {
  x = 0;

に対して type 情報を追加すると

class Foo {
  x :number = 0;

になるということなのですが、そもそもこの書き方が ES2015 の範囲外なので、Flow を利用してプロパティ / フィールドに type 情報を追加したい場合、Babel に

babel-plugin-transform-class-properties

を追加することが必要になります。

実際にはこんなアホな初期化ミスはないと思いますが、ローカル変数と違ってプロパティの場合はどこからアクセスされるか分からない長寿命な変数の一種と言ってよいので、type の恩恵はおおいにありそうです。

ちなみに

なんでこの書き方に思い至ったかというと、

TypeScript in 5 minutes &#183; TypeScript

を見て気づいたのでした。

結局 TypeScript の情報もチェックしてるよ!

あとはIDE的なものの対応がよく分からない

自分の場合は Emacs で読み書きして別途 flow や lint を動かすので構わないんだけど、IDE にこの辺の機能が組み込みの場合にどう扱ったらいいかは分からないです。実際 VS Code で開くと *.ts の場合は自動的に TypeScript と判定されて問題ないのですが、*.js の場合は type が書いてあると怒られます。

自動化の部分ではクリアできてるとは言え、いちいちコマンドを呼ばなくてよい、表示も統合されてて見やすいといった IDE のメリットがこのままではスポイルされてしまいます。

…と思ったら

Flow Language Support - Visual Studio Marketplace

を見ると

"javascript.validate.enable": false

するのが Known Issue になってた。うーーーーーーん。イマイチだなぁ。

ESLint - Visual Studio Marketplace

も、こまごま設定する必要があるんですな。この辺もバージョン管理にぶちこめるといいのかもしれないけど、それはそれでアレ。

まぁ今後の課題ということで。

  1. 開発環境を Visual Studio に、動作環境を MS プラットフォームに限定できるなら迷わず TypeScript でもよいと思います。 

  2. ※ ちなみに、今でも「Rubyのように全部式」を実現していた CoffeeScript の方が好きな部分はあります 

金沢でWiFiの使えるカフェ/喫茶店情報の断片

twitter で自分のノート PC を持ち込んで、WiFi でネットに繋いで作業できるカフェとかないかなという話題に。正直、金沢ではまだかなり少ないと思うよと断りつつ、知ってる情報を吐き出しておいた。

14:27:46 >wtnabe< @kabakiyo そんなとこあるんすかねぇ。自分でやったこと
                  あるのはビーンズのタリーズとその辺のマクドです。
14:34:53 <kabakiyo> @wtnabe 自分も知らないんで、あったらうれしいんです
                    けど... ビーンズのタリーズってネット使えます?
14:36:33 >wtnabe< @kabakiyo WiFiはないすね。そのときは自前 e-mobile で
                  した。
14:39:55 >wtnabe< @kabakiyo 御経塚サティのタリーズにはWiFiのサービス入っ
                  てますね。http://bit.ly/b4dOt
14:40:14 >wtnabe< @kabakiyo 「金沢」ではないですけど…。
14:41:49 >wtnabe< @kabakiyo あと路々が freespot 入れてますけど、休みの
                  日は意外なほどいっぱいになります…。みんな freepost
                  目当てじゃないと思いますが。
14:42:31 >wtnabe< @kabakiyo あと武蔵のコニーズアイって雑貨屋のカフェコー
                  ナーは使い放題です。
14:43:53 >wtnabe< テルメにも freespot 入ってるな。カフェじゃなくて温泉
                  になっちゃうけど。
14:45:27 >wtnabe< @kabakiyo あと角間のサークルK w  かろうじて金沢
14:46:53 <kabakiyo> @wtnabe おぉ、たくさんの情報ありがとうございます!
                    結構あるんですね。近々利用させてもらいます。助かり
                    ました! *Tw*
14:49:53 <kabakiyo> @wtnabe ちょっ、メモるの大変(汗 *Tw*
14:52:53 <yuuitiro> . @wtnabe @kabakiyo 僕もそれをかこうと思っていた。
                    電源も使えるよ。
14:53:52 >wtnabe< そういやマクドのDSダウンロードコーナーってDSしか使え
                  ないみたいでMacBookからは見えなかった気がする
14:54:12 >wtnabe< まー見えてもDS用のサービスにしか繋がらないんだろうか
                  ら意味ないと思うけど
14:58:07 >wtnabe< ぶっちゃけ自分はもう freespot 探す時間を e-mobile に
                  払う金に置き換えた方が安上がりだと思っちゃってますけ
                  どね。漫画喫茶で自前 MacBook + e-mobile もやったこと
                  あるw
15:01:53 <checkela> @wtnabe その通りだと思う
15:04:54 <kabakiyo> @wtnabe 確かに。 *Tw*
15:09:45 >wtnabe< .@kabakiyo @checkela それはともかく雰囲気のいい店を知
                  りたいすね。なかなか出会えないです。
15:13:53 <checkela> @wtnabe カフェ紹介した本を片手に巡るしか
15:18:19 >wtnabe< 女の子が文庫本読んでサマになるカフェとおっさんが
                  O'Reilly本とMacBook広げて許されるカフェは違うと思うん
                  だ…。 

まとめてて思ったけど、もしかしてテルメは合宿系にいいんじゃないかという気がした。街中ではないので車で移動するしかなく、他所の人を呼ぶのはつらいけど、車社会の北陸に住んでいる人はむしろインターに近いので集まりやすいし、あとは電源とかスクリーンとかホワイトボード辺りがなんとかなるとそれなりの規模をまかなえるんじゃないかろうか。

jsUnit 利用時は cache を切れ

そうかそうだよな。testRunner.html をどんだけスーパーリロードしても無意味だよね。ということで Webdeveloper から disable Cache するように > オレ

Safari だとキャッシュを空にするのはワンアクションでできるからいいんだけど、Firefox は奥まったところにあるから、つい億劫になっちゃうんだよねぇ。

やっぱ最近の梅雨は7月だよな

最近、オレが外に出るほんの一瞬に限ってやたら雨足が強くなる。

今日はそれに慌てて走ったらこけてズボンが 1.5cm ほど割けた。

オレが何をした。

こんなに真面目に頑張ってんのによ。

今週はどうも何もかもダメだな。とっとと終われ。

煮詰まってどうでしょうの録画も忘れるしよ。ほんと最悪。つかこれ早くチェックとか自動化しないと。何やってんだオレ。

FileUtils を作っていた

Ruby 1.7 で入った FileUtils ってモジュールがあるのに気づかずに、自分で FileUtils って class を作ってしまったorz まぁ別に車輪の再発明しまくったわけではないんで、名前変えるだけなんですが。

※ そのモジュールを使わないなら名前を変える必要がないのは承知のうえ。

Terminal から X11 アプリキター

export DISPLAY=":0.0"

setenv DISPLAY :0.0

のいずれかの指定がしてあり、X11 が起きていれば ok. X11 アプリは open -a を使わずに普通に

command &

で起動する。

しかし、w3m-ssl も入れてもう完璧だ、と思ったら Terminal はマウスイベントを検知できないのね。。。

jless

UNIXの部屋 の jless のページ

ひょっとすると jless で euc の出力ができれば Terminal のままでもいいかもしんない。

jless で euc キター

export JLESSCHARSET=japanese-euc

setenv JLESSCHARSET janapanese-euc

で。これで rxvt 不要になってもた。

大阪は球団を失い、プロ野球はファンを失うのか

阪神は西宮。近鉄と南海が大阪だったが、南海はもうずいぶん前に福岡ダイエーになった。今回近鉄がオリックスと合併し、オリックス側に吸収されるようなことがあれば大阪はプロ球団を失うということだな。

それにしてもプロスポーツはファンありきということを、日本の経営者で分かっているのは今のところ堀江社長だけに見えてしまうのは気のせいか。日本のプロ野球界全体の風潮が今回の買収騒動で皮肉にも浮き彫りになってしまっていないか。これでファンのためにメジャーに行かずに日本でやってくれなどと選手に話しているのだとしたら、あまりに見事な二枚舌と言わざるを得まい。

まぁファンのためにも健全経営は必要なんだから、球団を整理して収支を整え、ファンにも選手にも経営者にも安心なプロ野球を作るというのは大事なことだと思いますよ。そりゃそうです。でーもーさー。少なくともナベツネは選手もファンも大事にしてないのは見てりゃ誰にだって分かるんだからさ、他のオーナーは少なくともナベツネの露出を抑えるように努力すべきだと思うね。大相撲もそうだけど、あの人が口出してる競技って、なんかものすごく感じ悪いもの。ま、他のオーナーもファンと選手のことを大事にしてないっつんなら分かるんだけど。

Terminal は複数の文字エンコーディングに自動で対応できない

OS X の Terminal は複数の文字コードに対応できるが、それは手動で切り替える場合であって、例えば jless で jis の文字列を、Emacs で euc-jp の文字列を切り替えなしで表示することはできない。

これはメンドイ。

(どうも iTerm もその辺の問題はまだまだの感じ。そもそもボタン関係の日本語の表示自体、一部あやしいし。)

そこで Fink から X11 の rxvt-ml を apt-get install したが、考えたら TrueType フォントって X11 じゃそのまま使えないんだった。きったねー。とりあえずここまででやめる。

Fink

apt-get できるのは基本的にバイナリのみで、stable まで。

unstable をソースから入れたければ Fink コマンド。これは気分的には ports に似ている。

About

例によって個人のなんちゃらです