読者です 読者をやめる 読者になる 読者になる

Golang 覚書 その2

Go言語

qiita.com

やっとその2が書けた。。。 主にデータ構造について記載。

TOMLというミニマル言語

TOML

設定ファイルをjsonからTOMLに移行

ツールなんかを作るときある程度は自由度持たせるために設定をjsonで書いていたが、最近どうしてもカッコが面倒になってきた。
パラメータが少ない時なんかは問題無いんだけど、データが増えてくるとどうしても書くのが手間。(コメントも書けないし)
そんなことを思っていたらTOMLという物を発見。

# コメント 
Key1 = "Value1"
Array = [1, 2, 3]
[Object]
Key3 = "Value2"
[ObjectInArray]
Array = ["a","b","c"]

キーバリューペアの形式で書いていく形になる。
jsonの様にArrayやObject型などがあるため移行もしやすそう。

コメント

ハッシュ記号(#)から改行までがコメントとなる。

# コメントだよ
Key = Value #こんなのも可能

文字列

文字列の記述は4種類の方法がある。

基本

ダブルクォートで囲むと文字列として扱われる。
クォート、バックスラッシュなどはエスケープをする必要がある。

エスケープシーケンスの短縮形も用意されている。

\b         - backspace       (U+0008)
\t         - tab             (U+0009)
\n         - linefeed        (U+000A)
\f         - form feed       (U+000C)
\r         - carriage return (U+000D)
\"         - quote           (U+0022)
\/         - slash           (U+002F)
\\         - backslash       (U+005C)
\uXXXX     - unicode         (U+XXXX)
\UXXXXXXXX - unicode         (U+XXXXXXXX)

複数行文字列

改行も文字列として扱いたい場合、ダブルクォート3つで囲むことで表現出来る。
文字列の頭にすぐ改行を入れた場合その改行は無視される。

string = """
TOML Test
TOML Test"""

リテラル文字

正規表現のパターンを書くような場合、エスケープをするケースが増えとても面倒なケースが多い。
TOMLはリテラル文字列をサポートしているので、利用することでエスケープを省略して利用することが可能となっている。
リテラル文字を利用する場合シングルクォート囲むことで利用できる。

regex = \`[\d]+\'

複数リテラル文字

リテラル文字ではエスケープを利用することができないため、シングルクォートを利用することができない。
TOMLではリテラル文字の複数行をサポートしているのでそちらを利用する。
シングルクォートを3つで囲むことでリテラル文字として扱われる。

整数

全ての数は整数として扱われる。
正の数は頭にプラスを付けても、つけなくても表現できる。
負の数は頭にマイナスを付けて表現する。
大きな数字を表現する場合、アンダースコアを数字の間に挟むことで区切り表現をすることができる。

1_000
123_456_789

整数の表記を0から始めることはできず、2進数8進数16進数の形式で表現することは出来ない。
精度は64bit(long)

小数

小数部と指数部で表現が可能。
マイナス、プラスやアンダースコアでの区切りは整数と同じルールで利用可能

123.456_790

精度は64bit(double)

ブーリアン

ブーリアンはただのトークン。
小文字のみ利用可能。

日付

日付型はRFC 3339に準じる。(この規格しらないけど)
年-月-日T時:分:秒-UTCオフセットの形式になる。
UTCオフセットを0にする場合"年-月-日T時:分:秒Z"と記述すればよい。
日本のUTCオフセットは09:00なので 2016-02-29T00:00:00-09:00 となる。
タイムゾーンを利用するような場合以外は使わないとは思うが。
ちなみに秒には小数表現が可能。

配列

配列は[]この括弧で囲まれたプリミティブ型の集まり。
空白は無視され、要素はカンマで句切られる。
データ型は共通である必要がある。

array = [1, 2, 3]
matrix = [[1, 2, 3],[4, 5, 6]]
arrayStr = ["aa", "bb", "cc"]

テーブル

キーとバリューのペアからなる集まり。(jsonのオブジェクト型と同じ扱いができる)
テーブルはで囲まれたテーブル名から始まる。
配列表現と同じ括弧を利用するが、区別はしやすい。
配列の場合必ず値として表現するが、テーブルは値である必要はなく [table name] この様に記載する。

テーブルはで開始され、次のテーブルの開始またはファイルの終端までこのテーブルに属する。
使える文字は英数字、アンダースコア、ダッシュのみ(a-zA-Z0-9_-)

[table]
key1 = "value1"

key2 = "value2"

[table2]
key1 = "value1"
key2 = "value2"

と書いた場合jsonでは以下の構造を表現する。

{
  "table": {
    "key1": "value1",
    "key2": "value2"
  },
  "table2": {
    "key1": "value1",
    "key2": "value2"
  }
}

ネストしたテーブルを表現する場合ドットを利用する。

[table]
key1 = "value1"

key2 = "value2"

[table.NestTable]
key1 = "value1"
key2 = "value2"

この場合jsonで以下の構造を表現する。

{
  "table": {
    "key1": "value1",
    "key2": "value2",
    "NestTable": {
      "key1": "value1",
      "key2": "value2"
    }
  }
}

上位のテーブルを記載する必要が無い(値が存在しない)なら省略することも可能。
上位のテーブルを省略しても、後の行で上位のテーブルの内容を書くことはできる。
ただ、キーやテーブルの再定義は出来ないため、各定義は必ず1つである必要がある。

[table]
kay1 = "value1"

[table] # これはNG
kay2 = "value2"

テーブル配列

テーブルの再定義は行えないが、テーブルの配列を定義することはできる。
テーブル名を [ [table name] ] 括弧2重で囲むことで同じ名前のテーブルは配列の要素となる。
テーブルは表記順番で挿入され、キーとバリューのペアを持たないテーブルはからのテーブルとして扱われる。

[[TableArray]]
Key1 = "Value1"
[[TableArray]]
Key2 = "Value2"

これは以下のjsonの構造となる。

{
    "TableArray":[
        { "Key1" : "Value1" },
        { "Key2" : "Value2" }
    ]
}

ネストしたテーブルの配列も定義することができる。
その場合子テーブルにも括弧2重で囲めばよい。

まとめ

自分が使いそうな表記はこのぐらい。
頭でも書いたがjsonから機能の置き換えとしては十分。(むしろこっちのが良く思える)
パーサーも自分が使う言語はほぼあるので困ることはなさそう。

ただ、javascriptを使う時だけはなんとも言えない。
jsonはそのままjavascriptで使うことが出来るのに対して、TOMLは一度パーサーを通さないといけないから悩みどころ。
でも、製品で使う様な機能でない限りTOML採用かな。

参考URL
https://github.com/toml-lang/toml

※まだバージョンは0.4.0と1.0になってない所だけ注意

Go言語 覚書 その1

Go言語

最近go言語を始めたので、忘れないための覚書をqiitaに投稿。

qiita.com

とりあえず環境構築、制御構造、関数に関して記載

古いバージョンのUnityスクリプトリファレンスのURL

Unity

Unity5で開発をしている最中にUnity5.1がリリースされてUnity公式のAPIリファレンスも5.1に対応されたため、過去のAPIが確認できなくなってしまいとても焦った。 いろいろ調べて旧バージョンのUnityAPIを確認する方法がわかったので忘れないように残しておく

Unityの公式ページからスクリプトリファレンスのURLは下記になっている
(要は最新のスクリプトリファレンス)
http://docs.unity3d.com/ScriptReference/index.html

過去バージョンのスクリプトリファレンスを見たい場合はこちら
http://docs.unity3d.com/(version)/Documentation/ScriptReference/index.html

(バージョン)と書いてある所をUnity5なら500にして
http://docs.unity3d.com/500/Documentation/ScriptReference/index.html
Unity4.6ならば
http://docs.unity3d.com/460/Documentation/ScriptReference/index.html

としてアクセスすれば過去バージョンのAPIが確認できるっぽい。
ただ、マイナーバージョンの単位では存在するわけでなく、APIに更新の入るミドルバージョン以上の単位で存在する様に思われる。(ざっくりしか見てないからあってるのかわからないけど)
少なくとも 460, 500, 510は存在することを確認

UnityのPropertyDrawerでReorderableListを利用する

Unity

UnityでReorderableListが使えるようになっていたのでPropertyDrawerで指定出来るようにしてみた

ReorderableList

本当なら

public class ReorderableListTest : MonoBehaviour
{
    [ReorderableList]public List<int> data_;
}

こんな形でIntReorderableListみたいなクラスを作らないでメンバー変数に直接Listを持たせてAttributeの指定をすればいい形にしたかったがやり方がわからん。
Listに直接Attributeの指定をしてもサイズが1以上ないとPropertyDrawer側の関数が呼ばれなく、呼ばれたあともListクラスが保持しているメンバー変数がserializedPropertyに投げられるためReorderableListの生成が出来なかった。

そのためLIstを持ったクラスを宣言して、メンバーに持たせることでとりえあず回避。 Inspector拡張を利用すればこんな形にしなくて済みそうだが、ReorderableListのためだけに書くとなるとちょっと面倒。

なんか良い方法ないかなーー

初めてのcmake備忘録

最近vimを利用してC++を書く関係でmakefileを調べたりしてたが、先日cmakeを利用してのプロジェクト構築がmakefile書くよりも楽で便利にとても気に入ったので忘れないように備忘録として書いておこう。

ワーキングディレクトリ(cmakeの実行結果出力先)はどこでもいいが、引数で指定するcmkaeのソースパスにはCMakeLists.txtが配置されている必要がある。

実験で記載していたglfw、glew, boostを利用したプロジェクトのCMakeLists.txtはこちら。(自分の環境がmacなのでそれ以外は考えない!!)

初めてのcmake

CMakeLists.txtの用意ができてしまえばcmakeコマンドを実行して ビルド方法によって各ファイルを出力するだけ。

project_root
.
├── CMakeLists.txt
├── build
└── src
    └── main.

プロジェクトの構成としてはこんな感じになる。

ワーキングディレクトリがproject_rootだとしてそこで

cmake ./

とすることでproject_root直下にmake用の設定ファイルが出力される。

ワーキングディレクトリがproject_root/build にいる場合

cmake ../

因みにmakeではなくてxcodeで出力したい場合

cmake -G Xcode ./

と"-G Xcode"とオプションを指定すれば良い。

一番大事なCMakeLists.txtがほぼコピペで理解が浅いが一先ず使うことはできるので一先ずここまでにして後はちょいちょい調べてわかったことから徐々に記載していこう!!

vagrant使い方まとめ

vagrant

1.box取得

vagrant box add [**Box名**][**BoxのURL**]

上記のコマンドでboxを追加することができる。

DLするBoxはVagrantbox.esに記載されているのでこの中から選択して追加してやる

※追加したboxを確認する場合

vagrant box list

で確認することができる。

2.仮想マシンの作成

Boxの取得が完了したら仮想サーバーを作成してやる。 ※Vagrantoはサーバー単位でディレクトリを用意してやる必要があるので注意

サーバー用のディレクトリを作成したら移動を行い

vagrant init [**Box名**]

とすると現在いるディレクトリに"Vagrantfile"ファイルが作成される。 これが今作ったサーバーの設定ファイルとなる。

仮想サーバーの作成が完了したら

vagrant up

でサーバーが立ち上がる。

コマンド一覧

コマンド 内容
up 立ち上げ
halt 停止
status 状態
sleep スリープ
suspend スリープからの復帰
reload 再起動
destroy 削除

上記コマンドは

vagrant [コマンド]

の形で実行することができる。

vagrantで仮想サーバーを立ち上げる場合"Vagrantfile"とヒモ付されてるサーバーとなる。複数作成していた場合立ち上げたい対象を間違えないように気をつけよう!!

3.仮想マシンに接続

vagrant ssh

とすると立ち上げた仮想サーバーにvagrantユーザーでssh接続をしてのログインが行える。

4.ローカルネットワークでのアクセス

vagrantを立ち上げて色々と行った後にローカルネットワークでvagrantoにアクセスしたい場合"Vagrantfile"を編集してやる必要がある。 変更したいマシンの"Vagrantfile"を開いたら27行目のコメントアウトを解除してやれば同じ行に記載されているIPでアクセスが可能となる。

5.共有フォルダ

vagrantoは構築した時既に仮想マシン内の特定のディレクトリと"vagrantfile"があるディレクトリが最初から共有状態になっている。 共有されているディレクトリはルート直下の"/vagrant/" このディレクトリを外部公開ディレクトリに対してシンボリックリンクを貼ってやればファイル更新が楽になりそう。

試しに

vagrant ssh
cd /vagrant/
touch test.txt
exit
ls

とやればサーバーにログインして作ったファイルがホストOS側でも存在しているのが確認できる。(バージョン管理ソフト利用して落として来てもいいわけですが)

6.Provisioning

Provisioningとは"vagrant up"を行った後にシェルスクリプトなどを自動で実行してくれる。 同じサーバー設定を行いたい場合、この機能を利用してやることでより簡単に環境の構築を行える。

設定の方法はVagrantfileに "config.vm.provision :shell, :path => "provision.sh" とすることでpathで指定したシェルスクリプトの実行を行ってくれる。

vagranto upでProvisioningを実行してくれるのは初回立ち上げ時のようで2回目以降は実行してくれない様子

一度立ち上げた後にProvisioningを実行したい場合

vagrant provision

とすることで再度Provisioningの実行をしてくれる。

7.自分のBoxを作成する

必要なソフトをインストールした仮想マシンをパッケージングすることで、同じ状態のサーバーを再構築又はチーム内に共有を行うことができる。 作成した仮想マシンをパッケージングする場合

vagrant package

とすることでboxを作成することができる。 処理が終わったら現在のディレクトリにpackage.boxというファイルが出来る。 あとは工程1の時に行ったのと同じようにbox add [Box名][ファイル名**]とすることで自分で作成したBoxを新たに追加することができる。

Boxを追加した後の使い方は今までと同じ。(initで仮想マシンを作成、upで立ち上げ)