Laravel で Form を利用して、エラーだった場合にそれをどう返すかのサンプルコードは 4.2 でも 5.6 でも以下のように
- Validation - Laravel - The PHP Framework For Web Artisans
- Validation - Laravel - The PHP Framework For Web Artisans
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 のこのコードで初めて見たんだけど、こういう設計って推奨されるんですかねえ…?
背景
JavaScript はオブジェクトの構造とかコンパクトでプラットフォーム非依存な仕様など、面白いと思う反面、
'' < 1
が true になってしまうなど割とつらい仕様もあるので、大々的には入れたくないなぁと以前から感じていたのですが、ここ数年は JavaScript に型を入れるというのは AngularJS 2 の TypeScript 採用、Facebook の Flow など話題だし、ES2015 にはなんとかえっちらおっちら追いつけそうなので、いっちょ Flow でも試してみることにしました。
※ 私は Ruby を使っていますが、Ruby の場合は型が欲しいと思うことはありませんでした。Ruby にも静的型はないじゃないかと思うかもしれませんが、上のような謎挙動はないので、全然意味が違うということは添えておきたいと思います。
実際のところは直接書いたコードではなく簡易DSLのようなナニカで上の '' < 1 を踏み抜いてしまったことにより型の必要性を感じているので、これを入れればすぐ問題は解決、というわけにはいきませんが、興味が湧いちゃったのでまずはこれをやってみましょう。
判断基準
なぜ Flow なのか。以下を読むべし。
このエントリでは条件が整えば 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 · 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 · 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
も、こまごま設定する必要があるんですな。この辺もバージョン管理にぶちこめるといいのかもしれないけど、それはそれでアレ。
まぁ今後の課題ということで。
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広げて許されるカフェは違うと思うん
だ…。
まとめてて思ったけど、もしかしてテルメは合宿系にいいんじゃないかという気がした。街中ではないので車で移動するしかなく、他所の人を呼ぶのはつらいけど、車社会の北陸に住んでいる人はむしろインターに近いので集まりやすいし、あとは電源とかスクリーンとかホワイトボード辺りがなんとかなるとそれなりの規模をまかなえるんじゃないかろうか。
そうかそうだよな。testRunner.html をどんだけスーパーリロードしても無意味だよね。ということで Webdeveloper から disable Cache するように > オレ
Safari だとキャッシュを空にするのはワンアクションでできるからいいんだけど、Firefox は奥まったところにあるから、つい億劫になっちゃうんだよねぇ。
最近、オレが外に出るほんの一瞬に限ってやたら雨足が強くなる。
今日はそれに慌てて走ったらこけてズボンが 1.5cm ほど割けた。
オレが何をした。
こんなに真面目に頑張ってんのによ。
今週はどうも何もかもダメだな。とっとと終われ。
煮詰まってどうでしょうの録画も忘れるしよ。ほんと最悪。つかこれ早くチェックとか自動化しないと。何やってんだオレ。
Ruby 1.7 で入った FileUtils ってモジュールがあるのに気づかずに、自分で FileUtils って class を作ってしまったorz まぁ別に車輪の再発明しまくったわけではないんで、名前変えるだけなんですが。
※ そのモジュールを使わないなら名前を変える必要がないのは承知のうえ。
export DISPLAY=":0.0"
setenv DISPLAY :0.0
のいずれかの指定がしてあり、X11 が起きていれば ok. X11 アプリは open -a を使わずに普通に
command &
で起動する。
しかし、w3m-ssl も入れてもう完璧だ、と思ったら Terminal はマウスイベントを検知できないのね。。。
ひょっとすると jless で euc の出力ができれば Terminal のままでもいいかもしんない。
jless で euc キター
export JLESSCHARSET=japanese-euc
か
setenv JLESSCHARSET janapanese-euc
で。これで rxvt 不要になってもた。
阪神は西宮。近鉄と南海が大阪だったが、南海はもうずいぶん前に福岡ダイエーになった。今回近鉄がオリックスと合併し、オリックス側に吸収されるようなことがあれば大阪はプロ球団を失うということだな。
それにしてもプロスポーツはファンありきということを、日本の経営者で分かっているのは今のところ堀江社長だけに見えてしまうのは気のせいか。日本のプロ野球界全体の風潮が今回の買収騒動で皮肉にも浮き彫りになってしまっていないか。これでファンのためにメジャーに行かずに日本でやってくれなどと選手に話しているのだとしたら、あまりに見事な二枚舌と言わざるを得まい。
まぁファンのためにも健全経営は必要なんだから、球団を整理して収支を整え、ファンにも選手にも経営者にも安心なプロ野球を作るというのは大事なことだと思いますよ。そりゃそうです。でーもーさー。少なくともナベツネは選手もファンも大事にしてないのは見てりゃ誰にだって分かるんだからさ、他のオーナーは少なくともナベツネの露出を抑えるように努力すべきだと思うね。大相撲もそうだけど、あの人が口出してる競技って、なんかものすごく感じ悪いもの。ま、他のオーナーもファンと選手のことを大事にしてないっつんなら分かるんだけど。
OS X の Terminal は複数の文字コードに対応できるが、それは手動で切り替える場合であって、例えば jless で jis の文字列を、Emacs で euc-jp の文字列を切り替えなしで表示することはできない。
これはメンドイ。
(どうも iTerm もその辺の問題はまだまだの感じ。そもそもボタン関係の日本語の表示自体、一部あやしいし。)
そこで Fink から X11 の rxvt-ml を apt-get install したが、考えたら TrueType フォントって X11 じゃそのまま使えないんだった。きったねー。とりあえずここまででやめる。
apt-get できるのは基本的にバイナリのみで、stable まで。
unstable をソースから入れたければ Fink コマンド。これは気分的には ports に似ている。