write ahead log

ロールフォワード用

Excelファイルを読み書きするプログラミング言語を作った

できたのはコレ。折角作ったのでMSペイントで雑なロゴも作ってみたり。。。

github.com

ドキュメントも書いたし、技術的に興味のある方はGitHubへどうぞ。

残念ながら技術的にはすごいものではないけれど(buggyだし)。

何を使って作ったか

言語の処理系としてはgoとgoyaccを使って書きました。

これは雑に何か言語ぽいものを作るのに大変おすすめです。

GCも書かなくていいし、構文解析もいらないので形にしたいものまでかなり速くたどり着けます。

これ以上楽にやろうとするとRubyDSL書くとかかなぁ。

でも配布がクロスプラットフォーム&シングルバイナリなのはかなり利点かなと思います。

Excelファイルを操作するにはpure goで書かれたExcelizeというプロジェクトを使わせてもらってます。これは大変助かりました。

私が欲しかったもの

私は仕事でExcelファイルを読み書きするプログラムを結構な数書いてきました。

小さい会社相手の業務システムを作るという仕事も影響しているのか、大体のことは「Excelで」と言われます。(安いし)

データベースへの入力も出力も、帳票出力としてもExcelです。

前職では同僚との間で「結局、Excelなんだよ」という謎の合言葉もありました。

cellを作り始めた時にもwindowsのバッチファイルでファイル名とExcelの内容を書き換えてほしいという仕事をしていました。

「もうExcelを読み書きするだけの言語をくれよー」と思い始めたのが作るきっかけの一つでした。

Unixの思想を少し取り入れる

私は中二病的にCLIカッケーと思っちゃったところからプログラミングを始めた所があるので、割と*nixが好きです。

開発にもvimを使ってますし(プラグインはあまり使わないけど)、grepとかawkとかのCLIツールもちょこちょこ使います。

そういうわけでawkみたいにExcelをいじれる言語があればいいなぁという考えに至りました。

作り始めるきっかけになった本

実はcellを作るにあたってきっかけになった本が2冊あるので紹介したいと思います。

(どちらも癖が強くて万人向けじゃない気がするのですが)

1冊目はmatzさんの言語のしくみ。

内容はともかくこの人がプログラミング言語が好きという事が伝わってきます。

この本を読んで「yacc使ったことないし何か作ろうかなぁ」という気持ちになりました。

www.amazon.co.jp

2冊目はユニケージ原論。

www.amazon.co.jp

kindle Unlimitedに入っていた時にたまたまあったので、読んでみた本です。

CLIのパイプラインでかなりの事ができるよねと思い直させてくれました。(かなり過激だとは思いますが。。。)

読後に「現実の業務を見ると既にプレーンテキストじゃなくて全部Excelで回ってるよね」と思ったところからcellを作り始めました。

趣味プロジェクトをやりきるために

私個人としては物を作る時には2種類のものがあります。

  • 中身が気になるからとりあえず作ればわかるだろうと作るもの
  • なんかいいアイデアな気がするから作ってみるもの

cellは2つ目でした。

ただ、正直この手の個人プロジェクトはやりきるのが難しいです。

cell自体はほとんど他所の言語から持ってきただけの構文ですし、ライブラリを使った他の言語に比べて品質が良いわけでもありません。

優れていないものを使う理由もないので、実際作りきっても無意味かなと感じるのは自然でしょう。

こういう物を作る時、大体は「面白いからそれで良い」「曲がりなりにも言語を作った達成感があるからそれでいい」となるのですが、道具を作るのですから(少なくとも私は)「大して役に立たない物を作るむなしさ」みたいなものと戦う事になります。

そんな時、自分がちょっとだけ困っている問題に特化したものを作ると、「メンドクサイ事」を「自作の道具でほんの少しだけ楽できる(気分になる)事」に変えるものを作るというモチベーションが生まれるかもしれません。

(こういうのは納品したりプロダクションで使うものには使えないかもしれないけどね)

ブラウザで動くアウトラインエディタを作った

Vue.jsをもうちょっと触っといた方がいいかな, ぐらいの軽い気持ちで作っていたけどNetlifyだと無料で配信できるし公開しておく.

bonsai-outliner.netlify.app

どう見たってWorkFlowyとかDynalistを使う方が良いのだが, ショートカットをUnixキーバインドっぽく仕上げたら思いの外便利になってしまった.

Google Driveへの保存機能も作っていたが, APIの利用申請にYou Tube動画の登録が必要になって面倒になってやめた. (利用するAPIを絞れば大丈夫そうだけど, ふつーのテキストファイルで保存したいのよなぁ.あとDrive API調べるの面倒...)

自分が使う分にはテキストファイルへのエクスポートとブラウザ内への保存だけで十分だし, 案外このまましばらく使い続けるかもしれない.

余談だけど普段買わないWEB+DB PRESSのVol.120にあったVue.jsの入門記事が大変役に立った.

自作OS×自作ブラウザの記事の方が興味があって買ったのに、結局読み込んだのはVueの記事になってしまった.

私のように大して難しい仕事をしない人はこの記事とGoogleだけでも結構使えるようになる気がする.おすすめ.

gihyo.jp

Vagrantのubuntu(ubuntu/bionic64)で12ステップで作る組込みOS自作入門の環境を作った時のメモ

h8writeとターミナルアプリは諦めてホストOSのものを使った. (Windowsでteratermとkz_h8write)

VirtualBoxからUSBやシリアルポートを使う方法もあるようなのだけど, どうもうまくいかない.

USB Type-Cしかないマシンなのでその影響が出ている気がしないこともない.

クロスコンパイル用のbinutilsとgccは著者のサイトから取得してきた.

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install flex

# binutils
$ curl -OL http://kozos.jp/books/makeos/binutils-2.19.1.tar.gz
$ tar xfvz binutils-2.19.1.tar.gz
$ cd binutils-2.19.1/
$ ./configure --target=h8300-elf --disable-nls --disable-werror
$ make
$ sudo make install

# gcc
$ curl -OL http://kozos.jp/books/makeos/gcc-3.4.6.tar.gz
$ tar xfvz gcc-3.4.6.tar.gz
$ cd gcc-3.4.6/
$ vi gcc/collect2.c
# 書籍記載の内容通り変更
$ wget http://kozos.jp/books/makeos/patch-gcc-3.4.6-x64-h8300.txt
$ patch -p0 < patch-gcc-3.4.6-x64-h8300.txt
$ mkdir build && cd build
$ ../configure --target=h8300-elf --disable-nls --disable-threads --disable-shared --enable-languages=c --disable-werror
$ make
$ sudo make install

makeしたmotファイルをホスト側のh8writeで書き込めばとりあえずstep1はクリアできる.

VM便利だけど, いちいち面倒だしubuntuマシンが欲しくなる.

Laravel Duskで要素数を数えたり現れる順序をテストしたかった

直接的なアサーションがなかったから作った. TestCaseでuseして使うtraitにしてみた.

たぶんMacroを用意するのが正当なアプローチだと思うんだけど, 調べるの面倒で雑に書いてしまった.

<?php

namespace Tests;

use Facebook\WebDriver\WebDriverBy;

trait MyDuskAssertions
{
    /**
     * $selector要素が$count個あるかをassertionする
     * 
     * Usage:
     *   $this->myAssertElementsCountIs($browser, 'tbody>tr', 1);
     */
    public function myAssertElementsCountIs($browser, $selector, $count)
    {
        $elements = $browser->driver->findElements(WebDriverBy::cssSelector($selector));
        $this->assertCount($count, $elements);
    }

    /**
     * $textsが$selector内で順番に現れるかassertionする
     *
     * Usage:
     *   $this->myAssertSeeInOrder($browser, 'tbody td', ['No.1', 'No.2', 'No.3']);
     */
    public function myAssertSeeInOrder($browser, $selector, $texts)
    {
        $targets = $texts;
        $elements = $browser->driver->findElements(WebDriverBy::cssSelector($selector));
        $msg_texts = implode(',', $texts);

        foreach ($elements as $e) {
            $expect = reset($targets);

            if ($e->getText() == $expect || $e->getAttribute('value') == $expect) {
                array_shift($targets);
            }
        }
        $this->assertEmpty($targets, "'$msg_texts' were not see in order in '$selector'.");
    }
}

Laravel duskでinput type dateの入力を行いたい

なんかチョットハマったので.

<input type="date" id="due_date">

に対してこうやりたいんだけど, どうもうまくいかない.

->type('#due_date', '2020-01-01')

調べるとこうやるらしい.

->keys('#due_date', '2020', '{tab}', '01', '01')

微妙に面倒.

Laravelでテストする時にパスワードの更新を確認する

パスワードのハッシュを確認するメソッドを毎回忘れる.

// Hashファサードがいるよね
use Illuminate\Support\Facades\Hash;

// 普通の項目は以下でテストできる
$this->assertDatabaseHas('users', [
    'name' => '更新した名前',
    'email' => '更新したメールアドレス',
]);

// パスワードの確認はHash::checkを使う
$registed_user = User::where('email', '更新したメールアドレス')->first();
$this->assertTrue(Hash::check('期待されるパスワード', $registed_user->password));