「IoTフロントエンド開発」を考える ②nimyamlとnimongo

# 序
「IoTフロントエンド開発」なるものを考える、なるシリーズで、Nim言語で学びつつ、実案件化を目指すことにした。何の事はなのかは[ポエムっぽく書いたシリーズ①](http://qiita.com/kmry2045/items/7c8265cafe8de46dab4f)を参考のこと。今回は、NimでIoTするための学習教材として良いのではと考えている、２つのpure Nimライブラリ(Nimのみで書かれたライブラリ)を軽く取り上げる。

# 1. [nimyaml](https://nimyaml.org/)
名前の通り、NimでYAMLを扱うライブラリ。pythonと同様にインデントで記述していくnimとYAMLは、相性が良さそう。YAMLは、Ruby on RailsやPlay!などのwebフレームワークや構成管理ツールansible、さらに、nimのCI(継続インテグレーション)設定の記述にも使われている。

はじめに、やや長くなるが、pure NimなYAMLライブラリであるNimYAMLにおけるCI向けのYAML文書を見てみよう。

```.travis.yml
# Copied from https://github.com/nim-lang/Nim/wiki/TravisCI
language: c
env:
  # Build and test against the master and devel branches of Nim
  - BRANCH=master
  - BRANCH=devel
compiler:
  # Build and test using both gcc and clang
  - gcc
  - clang
matrix:
  allow_failures:
    # Ignore failures when building against the devel Nim branch
    - env: BRANCH=devel
  fast_finish: true

  - |
    if [ ! -x nim-$BRANCH/bin/nim ]; then
      git clone -b $BRANCH --depth 1 git://github.com/nim-lang/nim nim-$BRANCH/
      cd nim-$BRANCH
      git clone -b $BRANCH --depth 1 git://github.com/nim-lang/csources csources/
      cd csources
      sh build.sh
      cd ..
      rm -rf csources
      bin/nim c koch
      ./koch boot -d:release
    else
      cd nim-$BRANCH
      git fetch origin
      if ! git merge FETCH_HEAD | grep "Already up-to-date"; then
        bin/nim c koch
        ./koch boot -d:release
      fi
    fi
    cd ..
before_script:
    - export PATH="nim-$BRANCH/bin${PATH:+:$PATH}"
script:
    - nim lexerTests
    - nim parserTests
    - nim jsonTests
    - nim domTests
    - nim serializationTests
    - nim quickstartTests

#### 以下，略 ####
```

コンパイル対象言語(C)、対象ブランチ（master,devel）、使用コンパイラ(gcc, clang)... などが淡々と列挙されている中、install:のところに、bashスクリプトそのものが記述されている。記述の自由度が高いことか伺えるだろう。

##YAMLはJSONの上位互換。
Play!やansibleで、漠然などYAMLを作っていたので、考えたこともなかったのだけれど、YAMLはJSONの上位互換。すなわち、JSON文書はYAML文書に変換可能。逆のYAML文書をJSON文書に変換も、一工夫すれば、可能。

コード例は、以前書いた[Nimポエム](http://qiita.com/kmry2045/items/a4a687aba2d3189c993e#iot%E6%99%82%E4%BB%A3%E3%81%AB%E6%B4%BB%E3%81%8D%E3%81%9D%E3%81%86%E3%81%AAnimjsonyaml%E3%82%92%E6%89%B1%E3%81%86%E4%BE%8B)に書いた。IoT案件でのYAML自体の使いどころも、考えているんだけど、それはまたの機会に。

##ソースコードを読んでいく。

Nimのソースコードを読み始めて気がついたのは、はじめに冒頭のimport文を見ておくべきということ。
例えば、NimYAMLの
https://github.com/flyx/NimYAML/blob/devel/yaml/dom.nim
にある、dom.nimのimport文。
> import tables, streams, hashes, sets, strutils

tablesっていう、名前からは何かのテーブルなんだろうな、くらいしか分からないモジュールは要注意だ(dom.nimのソースコード中に、tablesというタームはここにした登場していない)。
幸い、nim本家サイトでは、標準ライブラリについて、けっこうしっかりと文書化されている。
http://nim-lang.org/docs/tables.html

ここをちら見して、tablesライブラリに、{1: "one", 2: "two"}.toTable とか、{1: "one", 2: "two"}.newTableといったメソッドがあることを知っておけば、

```dom.nim
proc newYamlNode*(fields: openarray[(YamlNode, YamlNode)],
                  tag: string = "?"): YamlNode =
  YamlNode(kind: yMapping, fields: newTable(fields), tag: tag)
```
といったコード中のnewTableの役割を推測するのに役立つ。

*※tablesライブラリはかなりメソッドの多い重要ライブラリの模様だ。*


# 2. nimongo
名前の通り、NimでMongoDbを扱うライブラリ。

本家のmongoドライバとは別途に、開発者の扱いやすいpure nim ライブラリとして開発されている。
>nimongo has a main intention to provide developer-friendly way to interact with MongoDB using Nim programming language without any other dependencies.


##ソースコードを読んでいく。

mongodbは，JSONを扱う有名どころの文書データベース。
mongodbは、内部的にバイナリ形式のJSONであるBSONを扱っている。nimでのバイナリの扱い方を知る上でも、[bson.nim](https://github.com/SSPkrolik/nimongo/blob/master/nimongo/bson.nim)はじっくり見ておきたいところ。
 先程と同様に、import文から見ていく。
 
 ```nim
import algorithm
import base64
import macros
import md5
import oids
import sequtils
import streams
import strutils
import times
import tables
```


 ソート機能などの基本アルゴリズムが集まったalgorithmライブラリなども気になるところだが、逆に、何をしているのかは明白なbase64ライブラリなどは、nimのソースコード読解入門によさそうだ。
 
http://nim-lang.org/docs/base64.html

```nim
import base64
let encoded = encode("Hello World")
echo(encoded) # SGVsbG8gV29ybGQ=
```

Nimの標準ライブラリのうちpure nimなものはいかに集められている模様。
https://github.com/nim-lang/Nim/tree/master/lib/pure

すでに多数のライブラリが収められている。時間がある時にひたすら読んでみたいものだ。

#お次は

IoT機器上のNim <--Internet--> サーバ側のNim <--> バックエンド(たぶんmongodb)
といったアーキテクチャを実現すべく、コーディングに着手したい。