北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

textlint の導入

textlintで日本語の自動校正サービスを作ってみた! | それいけ!フロントエンド

以前面倒だと思ってやってなかった textlint だけど、こちらのエントリの通りやったらさくっと動いた。

ざっくり手順。 npm の作法を知らないのが怖いところだけど、まあ、オプションまで含めてそのまま実行したら動いているので、多分大丈夫。

$ curl -L git.io/nodebrew | perl - setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
$ exec $SHELL -l
$ nodebrew install-binary v7.7.3
$ nodebrew use v7.7.3
$ npm init --yes
$ npm install --save textlint
$ npm install --save textlint-rule-preset-ja-technical-writing spellcheck-tech-word-textlint-rule
$ vi .textlintrc
$ vi package.json
$ npm run -s lint    # 直前に package.json に登録した内容

package.json はこんなの。

{
  ...
  "scripts": {
    "lint": "textlint */*.md",
    "lintfix": "textlint --fix */*.md",  
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "spellcheck-tech-word-textlint-rule": "^3.0.0",
    "textlint": "^7.3.0",
    "textlint-rule-preset-ja-technical-writing": "^0.1.3"
  },
  ...
}

.textlintrc はこんなの。

{
    "plugins": [
        "textlint-rule-preset-ja-technical-writing",
        "spellcheck-tech-word-textlint-rule"
    ],
    "rules": {
        "l-writing/sentence-length": false,
    "textlint-rule-preset-ja-technical-writing/sentence-length": false
    },
}

動くようになったので、後は好みの挙動にカスタマイズすればかなり便利に使えそうかな。

Server::Starter を利用できるサーバの実装

http://qiita.com/hiratara/items/2dacf8470c378b130d5c に書いたとおり。

下回りが苦手なので色々調べたのだけど、今回もGREEhttps://github.com/gree/haskell-prefork なるリポジトリが役に立った。 fork するだけじゃんと思って中を読むと、環境変数仕掛けた上で createProcess 使って自分自身を再度立ち上げる と言った涙ぐましい実装をしていたりする。古い unix パッケージの forkProcess のマルチコアで動いているとフォークできないみたいな制約を嫌ったのか、もしくは別のハマりどころがあってこんな実装をしているのか。

今回一番ハマったのが O_NONBLOCK にしないといけないってことだったのだけど、先のGREEのパッケージの例だと元のファイルディスクリプタHaskell で作っているので問題にならなかったのね、きっと。ちなみにその問題は、 waiのこのissued を見て解決した。

以前 Test::TCP 的なもの探したときもGREEhttps://github.com/gree/haskell-test-sandbox に当たった記憶がある。GREEすごい。

wai-graceful

wai-graceful の仕組みを眺めた。

warp 側に手を入れずにどうしてるのかと思ったら forkIO してサーバスレッドを別で立てといた上で、シグナル受け取ってからリクエスト捌き終わるまでメインスレッド残すのね。リクエストの処理が強制終了されることがないものの、シャットダウン中もリクエスト受け続けて 503 返し続けるのはどうなんだろ。リクエストを待ち続けていいのかも気になる・・・まあgracefulだからタイムアウトさせなくていいってのはあるかも。

そもそも warp ってシグナルどう扱ってるんだろ。

Windows 上での getChar のための no-buffering-workaround パッケージ

hiratara.hatenadiary.jp

エンターキーを押さないとキー入力を受け付けてくれない。大昔からチケットが上がっていて、

今日気がついたのだけど、Hackageにいい感じのパッケージが上がってる。

no-buffering-workaround: Workaround for GHC bug #2189.

使い方は initGetCharNoBuffering を呼んで ((ただし、こいつはNOP。UNIX環境だと NoBuffering を呼んでくれるので、その代わりに使っておくと良い)) 、 getChar の代わりに getCharNoBuffering を使うだけ。お手軽。

ただし、こいつで作った実行ファイルは msys2 上からはまともに動かない。PowerShellから叩くと、いい感じに動いた。

Unit への implicit conversion

内容はともかく気になったのが、

  def A_B_Cのつもりで書いた間違っているのにビルドが通る例(): Future[Unit] = {
    funcA()
      .map { _ =>funcB()}
      .map { _ =>funcC()}
    // ※たとえでこう書いていますが、本来はfor文とかを使いましょう
    // ※返値の型は本当はFuture[Future[Unit]]です。
  }

《Scala》Future[Unit]は気をつけて使おうの話

がなんでコンパイル通るのかなと思って *1 、 sub typing や ビルトインで定義されている implicit conversion を疑ってたんだけど、 Unit に関するものは見つからず、なんでだろうと。

答えは、単純に言語仕様だから、だった。

If e has some value type and the expected type is Unit, e is converted to the expected type by embedding it in the term { e; () }. https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html

*1:コメントの型も正しい意味なのやら

`stack setup --upgrade-cabal` した

lts-7.19 使ってたら嫌な感じのエラー。

    /tmp/stack25595/cairo-0.13.3.1/Setup.hs:8:29: error:
        • Couldn't match expected type ‘Distribution.Simple.UserHooks.UserHooks’
                      with actual type ‘Cabal-1.24.2.0:Distribution.Simple.UserHooks.UserHooks’
          NB: ‘Cabal-1.24.2.0:Distribution.Simple.UserHooks.UserHooks’
                is defined in ‘Distribution.Simple.UserHooks’
                    in package ‘Cabal-1.24.2.0’
              ‘Distribution.Simple.UserHooks.UserHooks’
                is defined in ‘Distribution.Simple.UserHooks’
                    in package ‘Cabal-1.24.0.0’
        • In the first argument of ‘defaultMainWithHooks’, namely
            ‘gtk2hsUserHooks’
          In the expression: defaultMainWithHooks gtk2hsUserHooks
          In an equation for ‘main’:
              main = defaultMainWithHooks gtk2hsUserHooks

ほぼ読んでない けど、

$ stack setup --upgrade-cabal

で解決。ついちょっと先日にもやった気がする。

build とか install じゃなくて setup なとこに注意。

とかやってたら、ghc-8.0.2 が使えるようになってた。

"hSetBuffering stdin NoBuffering doesn't work on Windows" とのこと

完全に序盤で投げ出されているけど、Haskellroguelikeを実装するエントリ。

https://github.com/jamiltron/Thieflike

Haskell には https://hackage.haskell.org/package/LambdaHack っていうroguelikeがあって そっちのほうが真面目に作られてるのだけど、CLIのバックエンドがvtyなのでwin環境では動かない。一方、Thieflikeはansi-terminalが使われているので動く。はずだったのだけど。

動かしてみると、エンターキーを押さないとキー入力を受け付けてくれない。大昔からチケットが上がっていて、

https://ghc.haskell.org/trac/ghc/ticket/2189

  • Milestone set to 6.8.3
  • Milestone changed from 6.8.3 to 6.10.1
  • Milestone changed from 6.10.1 to 6.10.2
  • Milestone changed from 6.10.2 to 6.12.1
  • Milestone changed from 6.12.1 to 6.12 branch
  • Milestone changed from 6.12 branch to 6.12.3
  • Milestone changed from 6.12.3 to 6.14.1
  • Priority changed from normal to low
  • Milestone changed from 7.0.1 to 7.0.2
  • Milestone changed from 7.0.2 to 7.2.1
  • Milestone changed from 7.2.1 to 7.4.1
  • Milestone changed from 7.4.1 to 7.6.1
  • Milestone changed from 7.6.1 to 7.6.2
  • Milestone changed from 7.6.2 to 7.10.1
  • Milestone changed from 7.10.1 to 7.12.1
  • Milestone changed from 7.12.1 to 8.0.1
  • Milestone changed from 8.0.1 to 7.10.3
  • Milestone changed from 7.10.3 to 8.0.1
  • Milestone 8.0.1 deleted

https://ghc.haskell.org/trac/ghc/ticket/11394

Milestone set to 8.4.1

という終わりの見えない状況で辛い。