2017/07/14


結構前から、そろそろ .NET Core を使ったお仕事とかやっていきたいなと思っていて、その際に Linux でちゃんと動くのかを確認しておきたかった。ただインターネットを見てもそれほど良い情報が見当たらず、これは誰も試してないのかもなと思い仕方がないので自分で作って体験してみる事にした。

GitHub - mattn/dotnet-blog

README.md dotnet-blog Markdown friendly blog engine inspired with Jekyll written in Microsoft .NET C...

https://github.com/mattn/dotnet-blog

Markdown で記事が書けて、Jekyll と同様に Liquid でテンプレート制御が行えて、さらに Git と連携するブログエンジンです。

ディレクトリ構成は Jekyll とほぼ同じで、_posts2017-07-13-タイトル.md の形式のファイルを置いたら勝手に _layouts の中のテンプレートが適用されてかっちょいいサイトで表示されるという物です。設定ファイルも _config.yml に書きます。

title: "塩梅ドットコム"
base-url: "http://mattn.apphb.com"
clone-url: https://github.com/mattn/dotnet-blog-posts.git

この clone-url に書かれたリポジトリから、_posts_layouts および _site といったファイルを git pull してローカルに展開します。サンプルのリポジトリも置いておきました。

GitHub - mattn/dotnet-blog-posts

Dismiss Join GitHub today GitHub is home to over 20 million developers working together to host and ...

https://github.com/mattn/dotnet-blog-posts

一度デプロイ出来たら、あとはこちらのリポジトリを更新してサイトの /pull に POST を送ると更新されます。この仕組みはもしかするといずれ変更するかもしれません。

トップ画面

トップ画面や

記事の画面

記事もきちんと表示されます。

とまぁ、こんな感じのブログエンジンを書いてみた訳だけど、実は今回はあえて Vim を使わず全て Visual Studio Code だけで開発を行った。これは仕事で使っていくなら僕だけじゃなく IDE を使いたい人がどの程度苦労するかも把握しておきたかったから。Visual Studio Code の C# 開発環境は以前まではそこそこ酷くて、まともな開発なんて出来ないんじゃないのって思ってたけど今回の開発でそのイメージは一蹴された。あの小気味良い軽快な動作をするエディタの様な IDE 上で、dotnet の restore やブレイクポイントを貼ったデバッグ、入力補完などほぼ問題なく扱えた。

また Windows で開発すると同時に Linux でも動作検証を行った。今回使った DotLiquid や CommonMark などは netcoreapp1.1 (.NET Core 1.1 ターゲット) でも問題無く使えていたし、publish して IIS 上で動作する事も確認出来た。気を付けないといけないのは、パス周りは「必ず」Path.Combine などを使うという事くらいだった。当初は 2~3 日くらいでこの検証を行う予定だったが、ちょっといろいろと忙しく1週間程度掛かってしまった。けれど開発の手順に慣れれば数日でそこそこ品質の良いマルチプラットフォーム向けのウェブアプリケーションを開発する事も出来るという結論に至った。まだテストスイートやインフラ周りで問題が無いかちゃんと検証できてないのでいきなり仕事で使おうとは思ってないけど、そこそこ近い未来で使う時が来るんじゃないかと思った。

C# 7 and .NET Core 2.0 Blueprints C# 7 and .NET Core 2.0 Blueprints
Dirk Strauss
Packt Publishing / (2018-02-06)
 
発送可能時間:


2017/07/11


Visual Studio Code で ssh 先のファイルを編集するには、Remote VSCode を使います。

Remote VSCode - Visual Studio Marketplace

A package that implements the Textmate's 'rmate' feature for VSCode.

https://marketplace.visualstudio.com/items?itemName=rafaelmaiolla.remote-vscode
なかなか仕組みが面白かったので紹介したいと思います。Remote VSCode は、実際は Sublime TextTextmate の rmate というコマンドの派生版です。どうやって ssh 先のファイルを編集するかというと、勘の良い方であれば以下のコマンドを見れば理屈は分かるはず。
$ ssh -R 52698:127.0.0.1:52698 user@example.org rmate /path/to/the/file.txt

rmate は Remote VSCode と通信してファイルの中身をやり取りします。実際には ssh でログインした際のポートフォワード機能によりリモート側のポート 52698 番で受け待ちすると同時に rmate コマンドを起動、ローカルで Remote VSCode と通信します。

rmate のプロトコルは至って簡単で、最初にファイルセットを送ります。

open
display-name: file.txt
data-on-save: yes
re-activate: yes
token: xxxxxxxxxxxxxxxx
data: 14

This is a file
.

以降は Remote VSCode が保存する度に以下のメッセージを送ってきます。

save
token: xxxxxxxxxxxxxxxx
data: 16
This is the file

面白い事にこの rmate、なぜだか色んな言語で実装されている。

Ruby version: https://github.com/textmate/rmate
Bash version: https://github.com/aurora/rmate
Perl version: https://github.com/davidolrik/rmate-perl
Python version: https://github.com/sclukey/rmate-python
Nim version: https://github.com/aurora/rmate-nim
C version: https://github.com/hanklords/rmate.c
Node.js version: https://github.com/jrnewell/jmate

いや、そんなにいらんやろw と思いつつも golang 版が無かったので作った。おとなげない。

GitHub - mattn/gomate

README.md gomate Edit files from an ssh session in TextMate/VSCode Usage 1 gomate /path/to/the/file....

https://github.com/mattn/gomate

まぁ、ssh してリモートで vim 使えばいいじゃんって思うけど、どうしても Visual Studio Code じゃないと嫌やねんって人はどうぞ。


2017/06/29


今日とある場所で虫が入り込む瞬間を見た。虫といってもバグの方。それはプログラマ向けの Q&A サイトで始まった。質問の内容はこうだ。

アース製薬 アース渦巻香 蚊取り線香 ジャンボ 50巻缶入 アース製薬 アース渦巻香 蚊取り線香 ジャンボ 50巻缶入

アース製薬 / ¥ 628 (2011-03-22)
 
発送可能時間:在庫あり。

文字列には0または4がだけが含まれる。文字列は 4 から始まり、例えば 440, 44, 40, 4400, 4440 など、これらは正しいとするが 404 は正しくない。今のところ、私は 0 の直後に 4 が現れるかどうかでチェックしている。これは果たして効率的だろうか。

始め僕はこの質問文をちゃんと読んでおらず、正規表現を使ってこれを実装した。

package main

import (
    "regexp"
)

func check(s stringbool {
    return regexp.MustCompile(`^4+0*$`).MatchString(s)
}

func main() {
    for _, tt := range []string{"444""44""40""4400""4440"} {
        if !check(tt) {
            panic("want true: " + tt)
        }
    }
    for _, tt := range []string{"404""040"} {
        if check(tt) {
            panic("want false: " + tt)
        }
    }
}

でも質問をよく見たら彼は効率的かどうかを気にしていた。確かにこのお題で正規表現は無い。僕は慌てて以下のコードを付け添えた。

package main

func check(s stringbool {
    i := 0
    r := []rune(s)
    for i = 0; i < len(r); i++ {
        if r[i] != '4' {
            break
        }
    }
    if i == 0 {
        return false
    }
    for ; i < len(r); i++ {
        if r[i] != '0' {
            return false
        }
    }
    return true
}

func main() {
    for _, tt := range []string{"444""44""40""4400""4440"} {
        if !check(tt) {
            panic("want true: " + tt)
        }
    }
    for _, tt := range []string{"404""040"} {
        if check(tt) {
            panic("want false: " + tt)
        }
    }
}

いずれのパッケージにも依存しておらく、おそらくちゃんと動くコードだろう。

フマキラー 線香 本練りジャンボタイプ函入 50巻 フマキラー 線香 本練りジャンボタイプ函入 50巻

フマキラー / ¥ 656 (2007-03-29)
 
発送可能時間:在庫あり。

その後、周りのオーディエンスが質問した彼に「どんなケースか良く分からないな、コードを見せてくれる?」と言った。そして彼は以下のコードを見せてくれた。

package main

import (
    "fmt"
    "strings"
)

func validate(str stringbool {

    if strings.HasPrefix(str, "4") {
        for i := 0; i < len(str)-1; i++ {
            if (str[i] == '0'&& (str[i+1== '4') {
                return false
            }
        }

    } else {
        return false
    }

    return true
}

func main() {

    data := []string{"4""44""4400""4440""404""004"}
    for _, val := range data {
        fmt.Println(validate(val))
    }
}

なるほど彼が最初に言ってた通り「0 の直後に 4 が現れる事でチェック」している。一見このコードは正しそうに見える。でもこのコードは「406」の様な文字列で正しく機能しない。彼にそれを伝えたところ、彼は「@mattn -1 最初に 0 と 4 しか無いっていったじゃん」と返してきた。

僕はここで「あー、バグが混入するタイミングはここなんだ」と思った。例えばこの関数が「4 から始まり 0 が 0 個以上続く文字列をチェックする」関数だとして他のユーザに配られるとする。それを譲り受けた開発者はそれを使ってテストする。この時点でその開発者は「もちろん 406 みたいな文字列も弾いてくれる」と信じてしまうだろう。こうやってバグってのは混入するんだ、と思った。まぁ、もしかしたら彼のキーボードには 0 と 4 とリターンキーしか付いていなかったのかもしれない。