頑張っているつもりのブログ

幅広くそれっぽい技術に関することを述べていきます

Go言語でつくるインタプリタを読了した

タイトル通り。Go言語でつくるインタプリタを読み終えました。 読み終えたというより、記載されているコードを実装し終えたと言ったほうがよいですかね。

https://www.amazon.co.jp/gp/product/4873118220

Rubyのしくみを少し読んだことあって、そこでインタプリタについて触れていたので、どういう実装の流れになるかなんとなくはわかってた のですが、実際に実装するのは初めてだったので、それとなく理解を深められた気がします。

github.com

流れ的には、 字句解析(lexer) -> 構文解析(parser) -> 評価(evaluator)と言う感じでした。 字句解析では文字列として受け取り、次の文字を検査して、対応するトークンに当てはめる。 構文解析トークン列からASTを定義していき、 評価は定義されたASTから実際の処理を行う。をコードで実践して学ぶことが出来ました。

まあ読み終えた感想をちょっと書こうかなーと。

よかったこと・疑問に思ったこと

インタプリタの実装を学べたのも良かったけど、Goで実装されていたのでそれ自体の学びにもなった。

interface の活用方法も良かったし、最近spockというテストフレームワークいいなと思っていたので、テーブルドリブンテストを用いたテストの書き方はとても良かった。

あとは、テストを先に記述するスタイルだったので、その雰囲気が掴めたこともよかった。 同じようなテストをコピペしていくのもだんだんめんどくさくなってくる

それでも、パッケージ名は *_test ではないことが少し疑問ではありました。対象のテスト関数がpublicだったのもあって、別にprivate関数にアクセスする必要ないんじゃない?と。

アサーションを用いるところでは(特にswitch)、同じ変数に代入していましたが、変数を束縛したい気持ちのある性分ですこし疑問でした。

「あ、ジェネリクス欲しくね...?」って思う時があった。slice定義の局面で。 []int{} []string{} を受け取ることができれば、下記のコード部分も ArrayObject 評価するテストが楽になったのではないかと思ってしまいました...

gopter/evaluator_test.go at master · wasanx25/gopter · GitHub

良さそうな記事もありましたが、やっぱう〜んというかんじですよね。

【Go言語】[]string, []int to []interface{} とかそういうの - DRYな備忘録

まあGoを書き続けるなら筋力が必要。

まとめ

Goとインタプリタの実装を学ぶことが出来たので良かったです。ベースがコードなので進めやすい。

いい本でしたっ。

Goでjsonファイルを読み込んでHTTPで表示する

簡単にjsonファイルをHTTPで読み込めるものを実装しました。Goで。

背景

開発において、HTTP APIを実装してそのクライアントを実装するという流れがあると思います。 APIが返すjsonファイル(モック)は出来たがまだAPIの実装が終わっていない時にクライアントの実装に着手したい場合、jsonファイルを読み込んで実装しなきゃ行けなかったりすると思います。 その結果、本番では使わないファイルを読み込む処理を余計に書かなきゃいけないので若干面倒です。

そんなときにjsonファイルを読み込んでHTTP APIとして動かし、簡単にモックを使ってクライアントの実装ができるようにするためにrimeというものを実装しました。

実装

GitHub - wataru0225/rime: Rime is simple json server.

使い方は非常にシンプルで、jsonファイルが格納されているディレクトリに rime コマンドを実行するだけ。

$ tree samples
samples
├── carts
│   └── item.json
├── user.json
└── users
    ├── item.json
    └── post.json

2 directories, 4 files
$ rime
2018/01/26 21:35:32 http://localhost:8080
2018/01/26 21:35:32 See browse -> http://localhost:8080/samples/carts/item.json
2018/01/26 21:35:32 See browse -> http://localhost:8080/samples/user.json
2018/01/26 21:35:32 See browse -> http://localhost:8080/samples/users/item.json
2018/01/26 21:35:32 See browse -> http://localhost:8080/samples/users/post.json

.json ファイルだけを確認して、そのファイルパスも含めてURLとしてjsonを扱ってくれます。なので、 .git ディレクトリなどがあったとしても対象外になるので、気にせず使うことができます。

オプション

ポートがデフォルトで 8080 を使ってるのですが、クライアントが 8080 を使う場合、被ってしまうのでポートが指定できるオプションをつけてあります。

$ rime --port 9000
2018/01/26 21:56:49 http://localhost:9000
...

まとめ

標準ライブラリしか使ってないし、コード量少ないのでシンプルにできた。 ただバージョン 0.0.1からスタートしてしまったのは、公開している。(今から1.0.0に変更できるけど、あえてしない。) ちなみに今は0.0.2。

ArchLinuxをインストールする

前回作った自作PCにArchLinuxをインストールしてみようと思いました。開発用ではDebianかNixOSかMac、サーバーではUbuntuCentOSを使ってきたので、自作PCではなんか新しいLinuxを入れてみようと思っていました。

名前だけ聞いたことが合ったのがGentooかArchLinuxで、どちらにしようかと思っていたのですが、なんとなくかっこいいと思ったArchLinuxを採用しました。

ちなみにその後聞いたのですが、Gentooはインストールするのにやたら時間がかかるらしいので、Gentooを選ぶとしんどかったんだなと思いました。

ArchLinuxのイメージをUSBメモリにコピーする

まずは、ArchLinuxのisoを公式ページからインストールする。下記のURLからインストールできる。 2017.11.01のisoファイルをダウンロードしました。

Arch Linux - Downloads

iosファイルをUSBメモリにコピーする

$ hdiutil convert -format UDRW -o arch archlinux-2017.11.01-x86_64.iso
- USB メモリのFileSystemの箇所を把握します
$ df -h 
$ sudo dd if=arch.dmg of=#{ディスクの位置} bs=1m
- 失敗した場合、対象のアンマウントしておく。Mounted onの箇所
$ diskutil umount #{USBディスクのMounted on}
- サイドddコマンドを実行
$ sudo dd if=arch.dmg of=#{ディスクの位置} bs=1m

これでUSBメモリにコピーすることができました。

USBメモリ自作PCに付けて、それをSSDにコピーする

ArchLinuxのイメージをコピーしたUSBメモリ自作pcに取り付けます。BIOS画面からUSBメモリから起動する設定をします。 それで再起動します。

WIFIの設定

最初はどうしようもないので、有線を使ってルーターに繋げます。pingで適当なドメインを叩いて返って来ればおけです。

有線を繋げた時点で、pingが通るはずですが、たまに接続できなかったりするので、その時は、 dhcpcd コマンドを打ってあげましょう。

そして、WIFI繋げます

$ sudo pacman -S wpa_supplicant 
- ネットワークのインターフェイスを確認します。
$ ip link show
$ wpa_supplicant -B -i <INTERFACE> -c <(wpa_passphrase <ID> <PASS>)
$ dhcpcd

IDとPASSは、WIFIのそれを設定してください。

繋げたら、pacmanのupdateしとくといいと思います。

$ sudo pacman -Syu

色々作業するためのpkgをインストール

$ sudo pacman -S sudo vim tree wget git

あと、非公式パッケージインストールするためのyaourtをインストールしておく。何かと使ったりする。

$ sudo pacman --sync --refresh yaourt

GNOMEのインストール

まずは、ドライバーのインストール。GTX 1070を使ってるので、NVIDIAのドライバーが必要。またそのへんのためのpkgをインストールしなきゃいけない

$ sudo pacman -S nvidia

GNOMEをインストール

X.orgのインストール

$ sudo pacman -S xorg-server xorg-apps xorg-xinit xterm

(WW) Open ACPI failed (/var/run/acpid.socket) (No such file or directory)の警告が出た時

$ sudo pacman -S acpid

GNOMEのインストール

$ pacman -S gnome gnome-tweak-tool

設定ファイルにグラフィックボードのPCI BusIDを確認する

$ nvidia-xconfig --query-gpu-info

PCI BusIDを設定ファイルに記述する。以下は/etc/X11/xorg.confのサンプル。

Section "Device"
        Identifier  "nvidia"
        Driver      "nvidia"
        BusID       "PCI:14:0:0"
        Option      "AllowEmptyInitialConfiguration"
        Option      "PrimaryGPU" "yes"
EndSection

また設定していく中で、出会ったエラーがあるが、 「Device(s) detected, but none match those in the config file」が出た時は、グラボへのドライバが正しく動いてないので、設定ファイルを確認する。

「open /dev/dri/card0: No such file or directory」 って言われたらグラボのドライバーがちゃんとインストールされてない。

起動したときにGNOMEが起動するようにする。/etc/X11/xinitにあるxinitrcをコピーして、ホームディレクトリに配置。そして、グラボから起動するようにするために下記をコピーしたファイルの上部に追加。

xrandr --setprovideroutputsource modesetting NVIDIA-0
xrandr --auto

最後にGNOMEを起動するためにディスプレイマネージャーの設定をします。GDMというのを自動起動するように設定します。

$ systemctl enable gdm

これでrebootすれば、かっこいいGUI画面が表示されます。

GUIからのWIFI設定

GUIからのWIFI設定をします。ただ最初、NetworkManagerがないみたいなことを言ってくるので、pkgをインストールします。

$ sudo pacman -S network-manager
$ sudo systemctl start NetworkManager.service #起動
$ sudo systemctl enable NetworkManager.service # 自動起動設定

GoogleChromeのインストール

GoogleChromeは公式ページだと、Debian系もしくはFedora系のダウンロードしか出来ないようなので、pkgからビルドすることに。 makepkg コマンドを使用するので、 base-devel というpkgをインストールする必要があります。

$ sudo pacman -S base-devel
$ git clone https://aur.archlinux.org/google-chrome.git
$ cd google-chrome
$ makepkg -s
$ sudo pacman -U google-chrome-*.pkg.tar.xz
$ google-chrome-stable # これで起動出来ます。

日本語化する

日本語表示するのはpkgをインストールすれば、完了でした。

$ sudo pacman -S fcitx-im fcitx-configtool fcitx-mozc

インストール後再起動をすると、GNOMEの設定画面からfcitx設定というのが出てくるので、そこで表示されているmozcを選択すると、漢字かな変換を使うことができます。(一度skkをインストールして、使おうとしたところ漢字の変換ができなかったので、mozcを使うのが個人的には良いと思います。)

キーボード設定

日本語配列のキーボードしか持ってなかったので、設定が面倒だなと思ってた。ので、US配列のHHKBを買って、お金で解決を果たす。

まとめ

OSを一からインストールするのは結構大変だったけど、動くようになって良かった。フォントが気にくわない状況になっているので、それをとりあえずどうにかしたい。 時にはお金で解決するのも大事。

自作PCを作った話

f:id:aild_arch_bfmv:20171110230132j:plain

自作PCを作ってみたいなーと常々思っていたのだが、ようやくノリと勢いでパーツを買って組み立ててみた。

パーツ表

種類 型番 値段
CPU AMD CPU Ryzen5 3.6GHz 6コア 12スレッド YD1600BBAEBOX ¥23,707
メモリ DDR4 2133 8GB 2枚 KVR21N15S8K2/16 ¥20,340
マザーボード ASRock AMD x370 PROFESSIONAL GAMING ¥27,810
SSD 240GB WDS240G1G0A ¥9,979
HDD Seagate BarraCuda 3.5インチ 3TB ST3000DM008 ¥7,904
CD/DVDドライブ ASUSTek DRW-24D5MT ¥2,512
電源 600W KRPW-PT600W/92+ REV2.0 ¥9,063
PCケース 黒透 JAX-02W ¥4,320
GPU GeForce GTX 1070 AERO ITX 8G OC ¥49,480

合計金額 155115円。思ったより(ちゃんとしたの作ろうとしたら25万ぐらいかかると思っていたから)安く済んだ。 Ryzen7にしなかったり、GTX 1080とかにしなかったり、ちょいちょい予算を抑えたつもりだったけど、15万円越えてしまった。。。

ちなみにamazonで注文したのですが、電源をカートに入れ忘れるという失態で、1日遅延して電源が届きました。

f:id:aild_arch_bfmv:20171110230138j:plain
1日遅れてやってきた電源

組み立て

マザーボードとCPUとメモリ

ググりつつ、ハードウェアの組み立ては全く未経験なので、文面だけでは理解するのが困難だったので、youtubeで動画検索をして組み立てる流れを調べました。 そのおかげで理解できて、マザーボードにCPUとファンとメモリを取り付け電源を繋ぐところまでいきましたが、ディスプレイに繋ぐ方法がよくわからなかった。。。

f:id:aild_arch_bfmv:20171110232202j:plain
CMOSクリアするときに外した電池が外したままなのですが、気にしないでください。)

というかマザーボードに5つのUSBとtype-cがあるぐらいで、「あーtype-cにつなぐのか」と思ってやってみたけど、画面が表示されず。。。

会社の先輩に自作PC作ったことがある人に聞くと、「Ryzenは、ビデオカードがないので、つけなきゃいけない」って言われたので、グラボを取り付けてディスプレイに繋いでみるといけた!! こういうとき、聞ける人が身近にいるのが大事。

ケースに入れて、SSDとHDDとドライブを取り付けて配線

ディスプレイに繋ぐまで時間がやたらとかかってしまったが、ここからの作業は意外とスムーズだった。 ケースに SSD、HDD、ドライブを取り付けるところがちゃんとあるので、これまた僕が買ったPCケース(黒透)で組み立てている動画を発見したので、それを参考にして組み立てたらいけた!

f:id:aild_arch_bfmv:20171110232934j:plain

最後は、ケースを閉めて、電源を入れてBIOS画面が起動できたら完成。

f:id:aild_arch_bfmv:20171110233013j:plain
なんかかっこいい

f:id:aild_arch_bfmv:20171110233008j:plain
BIOS画面もなんとなくかっこいい

所感

初めてのことでかなり時間を食った。けど、インターネットで調べると、結構わかりやすく説明してくれる記事や動画があったので、やっぱインターネットは素晴らしいなぁと。 あとは身近に聞ける環境にいたのも大きい。もし聞けなかったら、15万は頓挫する可能性はあった。

マザーボードGPUが差せるスロットが二つあるので、金銭的に余裕ができたら追加してもいいかなーという感じです。