第28回基準値を超えるシェル芸勉強会のまとめ

Pocket
LINEで送る

参加者の方々、会場でお手伝いいただいた方々、サテライトの主催・参加のみなさま、会場を提供いただいたさくらインターネットさん、横田さん、午前講師の今泉さん、共催のjusさん並びにりゅうちさん、LT発表者のみなさま、ありがとうございました。

総括的なコメント

最近、会場の半分くらいの人たちのレベルが人間離れしていますが、初心者でも楽しめる雰囲気はキープできたかと・・・。問題は実用的かつ高難易度でした。

今回は募集が早すぎてドタキャンが多くゆったりめでした。

問題はこちらです。

話が前後しますが、午前の部は今泉さんのシグナルに関するレクチャーでした。ありがとうございました。個人的には擬似シグナル0番というのを知らなかったです。

当日の様子

Twitter上での様子

サテライトの様子

大阪のLTのスライドはこちらにあります。

LTやブログのリンク

写真など

昼食
LT

Pocket
LINEで送る

【問題と解答】第28回基準値を超えるシェル芸勉強会

Pocket
LINEで送る

問題のみのページはこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.28

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

注意

今回はいつにも増して一般解を出そうとすると死にますので、欲しい出力が得られればそれで良いということを心がけましょう。

イントロ

Q1

Q1.1

contents.txtについて、「\begin{figure}と\end{figure}」で囲まれた部分を全て抽出してください。

Q1.2

次のようなリストを作ってください。

世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

解答

Q1.1については、次のようにsedの範囲指定を使います。

$ cat contents.tex | sed -n '/\\begin{figure}/,/\\end{figure}/p'
\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.5\linewidth]{./figs/coordinate.eps}
		\caption{世界座標系とロボットの姿勢}
		\label{fig:coordinate}
	\end{center}
\end{figure}
(中略。略していないものも含めて全部で4つ)
\begin{figure}[htbp]
	\begin{center}
		\includegraphics[width=0.8\linewidth]{./figs/observation_noise.eps}
		\caption{ランドマークの計測値の不確かさを表す共分散行列}
		\label{fig:observation_noise}
	\end{center}
\end{figure}

Q1.2については、不要なデータを削って最後に並び替えます。

$ cat contents.tex | sed -n '/\\begin{figure}/,/\\end{figure}/p' |
 grep -e include -e caption | sed 's/.*{//' |
 xargs -n 2 | tr -d '}' | awk '{print $2,$1}'
世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

Q2

\sectionから始まる部分を章としたとき、第2章の第1文を抽出してみましょう。ただし、各行の%以降はコメントアウトされた文なので無視してください。

解答

最初に段落番号をつけると簡単になります。

$ awk '/\\section/{a+=1}{print a,$0}' contents.tex | grep ^2 |
 grep -v '\\section' | grep -v '%.*' | sed 's/^..//' |
 sed -n '1,/。/p' | sed 's/。.*/。/'

平面上を移動し、向きを持ち、カメラでランドマーク観測ができるロボットで
graph-based SLAMを実行する方法を考える。

Q3

脚注(\footnote{…})の部分を全て抽出してください。一つだけ、脚注の中にも{}で囲まれた部分があるので注意してください。

解答

まずは脚注の終わりが必ず「。」で終わっているのを利用したズル解答から。grep -Pの最短一致を使います。

$ tr -d '\n' < contents.tex | grep -oP '(\\footnote{.+?。})'
\footnote{この仮定は実用上強すぎるが、実際には、後の計算式から分かるように、2つの姿勢間での値$\psi_{c,t}, \psi_{c,t'}$の差だけが分かれば良い。例えば、2点間で得られた画像の向きを画像処理から割り出すなどの処理で、この差は得られる。}
\footnote{$「10$[\%]」は変数にすべきだが、記号が増えて理解の妨げになるので固定値として説明する。}
\footnote{おそらく$\psi$は$\theta$で置き換えられるので$\psi$を使わない実装もできるが、まだ自分自身では検証していない。}
\footnote{小さい角度なので、$\sin(3\pi/180)$は$3\pi/180$に近似しても良い。}
\footnote{固定しないと世界座標系が決まらない。}

そうでない解は、インデントをつけてから抽出する方法しか、今のところ思いついていません。

$ tr -d '\n' < contents.tex | sed 's/[{}]/\n&\n/g' | sed 's/\\footnote/\n&/' |
 awk '{for(a=0;a<i;a++)printf " "}/{/{i+=1}/}/{i-=1}{print}' |
 sed -n '/\\footnote/,/^ }/p' | tr -d '\n' | sed 's/\\footnote/\n&/g' |
 sed 's/ *} */}/g' | sed 's/ *{ */{/g' | awk '{print}'

Q4

各章(\sectionから次の\sectionまでの部分)を、ファイル名にタイトルをつけて個別のファイルに分けてください。ファイル名のスペースはアンダースコアに変えても構いません。

解答

$ cat contents.tex |
 awk '/\\section/{f=gensub(/ /,"_","g",$0);gsub(/\\section{/,"",f);
gsub(/}$/,"",f)}{print $0 > f}'
###このようにファイルができます###
$ ls
contents.tex  graph-based_SLAMの実装例  はじめに  問題

Q5

このテキストには「○○座標系」という用語がいくつか出てきます。○○にはカタカナか漢字の単語が入ります。これらの「○○座標系」を全通り抽出してください。

解答

$ grep 座標系 contents.tex | mecab -O wakati |
 grep -oE '[^ あ-ん]+ 座標 系' | sort -u | tr -d " "
ロボット座標系
計測座標系
世界座標系
$ grep 座標系 contents.tex | grep -oE '[^ あ-ん{、「]+座標系' | sort -u
ロボット座標系
計測座標系
世界座標系

Q6

各段落の頭に全角スペースを入れてください。

解答

空行を見つけてフラグを立て、普通の文頭かどうか判断して全角スペースを差し込みます。

$ cat contents.tex |
 awk '/^ *$/{f=1}
{if(f && !/^ *$|section|begin|end|^%/){print " "$0;f=0}else{print}}'

Q7

本文の余計な改行を取ってください。(段落内の余計な改行を取るということです。)

解答

q6の出力から続ける例を示します。ゴリ押しです。

$ cat q6 | sed 's/^%.*//' |
 awk '/begin/{if(!stop)print "";stop+=1}
  !stop && !/section/{printf($0)}
  stop || /section/{print}/end/{stop-=1}' |
 sed 's/  /n  /' | sed 's/\\[sub]*section/\n\n&/' 

Q8

contents.texについて、次のように章節項のリストを作ってください。

1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く

解答

awkで章節項のカウンタを作ってうまく制御するのが一番素直な方法です。(二番目以降は思いつきませんが。)

$ grep section contents.tex | sed 's/{/ /' | grep -v ^% |
 sed 's/\\label.*//' | sed 's/}$//' |
 awk '/^\\se/{s+=1;$1=s;ss=0;print}/\\subse/{ss+=1;$1=s"."ss;sss=0;print}/
\\subsub/{sss+=1;$1=s"."ss"."sss;print}'
1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く
Pocket
LINEで送る

【問題のみ】第28回基準値を超えるシェル芸勉強会

Pocket
LINEで送る

解答例はこちら

問題で使うファイル等

GitHubにあります。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.28

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

注意

今回はいつにも増して一般解を出そうとすると死にますので、欲しい出力が得られればそれで良いということを心がけましょう。

イントロ

Q1

Q1.1

contents.txtについて、「\begin{figure}と\end{figure}」で囲まれた部分を全て抽出してください。

Q1.2

次のようなリストを作ってください。

世界座標系とロボットの姿勢 ./figs/coordinate.eps
計測値 ./figs/observation.eps
ランドマークの計測値から2点の相対姿勢を求める ./figs/two_poses.eps
ランドマークの計測値の不確かさを表す共分散行列 ./figs/observation_noise.eps

Q2

\sectionから始まる部分を章としたとき、第2章の第1文を抽出してみましょう。ただし、各行の%以降はコメントアウトされた文なので無視してください。

Q3

脚注(\footnote{…})の部分を全て抽出してください。一つだけ、脚注の中にも{}で囲まれた部分があるので注意してください。

Q4

各章(\sectionから次の\sectionまでの部分)を、ファイル名にタイトルをつけて個別のファイルに分けてください。ファイル名のスペースはアンダースコアに変えても構いません。

Q5

このテキストには「○○座標系」という用語がいくつか出てきます。○○にはカタカナか漢字の単語が入ります。これらの「○○座標系」を全通り抽出してください。

Q6

各段落の頭に全角スペースを入れてください。

Q7

本文のところだけ改行を取ってください。

Q8

contents.texについて、次のように章節項のリストを作ってください。

1 はじめに
2 問題
2.1 ロボットの姿勢と座標系
2.2 観測
2.2.1 ランドマークの識別
2.2.2 ランドマークの姿勢計測
2.2.3 計測値の記録
2.2.4 計測値の誤差
2.3 完全SLAM問題
3 graph-based SLAMの実装例
3.1 グラフのエッジを作る
3.1.1 $\V{\mu}_{c,t,t'}, \V{e}_{c,t,t'}$の計算
3.1.2 $\Sigma_{c,t,t'}, \Omega_{c,t,t'}$の計算
3.2 最適化問題を作る
3.2.1 マハラノビス距離
3.2.2 最適化する式
3.3 $\V{e}_{c,t,t'}$の勾配を求める
3.4 問題を解く
Pocket
LINEで送る

日記 — graph-based SLAMの解説文(書きかけ)、OS不具合尻拭いスクリプト、ますとどん、今週はシェル芸勉強会

Pocket
LINEで送る

今週末のことを重要なことから。

graph-based SLAMの解説書

確率ロボティクスの日本語ドキュメント・サンプル充実プロジェクトとして、先週はコードのサンプルをjupyter notebookに書くということをやっていましたが、今週は数式で解説するための文章を書いてました。うん。10年仕事が遅い。

まだ書きかけで粗いですが、世界で一番簡単に理解できるようにするつもりです。

Raspberry Pi3にUbuntu 16.04 Serverをインストールするときの便利スクリプト

3月以来、device treeのアドレスがアレでOSをアップデートするとクラッシュするというアレな感じになっている https://wiki.ubuntu.com/ARM/RaspberryPi のラズパイ3用Ubuntu 16.04イメージですが、今度はアップデートでwlan0が見えなくなるというアレな状況になりました。いくらサポートしてないからと言ってなんなんでしょう。

ということで、これらの不具合を回避しながらカーネルをアップデートするためのシェルスクリプトをGitHubのryuichiueda/raspimouse_book_ubuntu_initに置きました。このリポジトリにある after_os_install.bashです。ここにも同じコードを貼りつけておきます。 https://wiki.ubuntu.com/ARM/RaspberryPiのイメージをmicroSDに書き込んでOSを立ち上げてsshでログインし、すぐに適用します。

#!/bin/bash
# (c) 2017 Ryuichi Ueda
# This software is released under the MIT License, see LICENSE at https://github.com/ryuichiueda/raspimouse_book_ubuntu_init.

tmp=/tmp/$$

### purge of the cloud-init ###
sudo apt -y purge cloud-init

### remove the bug on the device tree address ###
cat /boot/firmware/config.txt                                           |
sudo tee /boot/firmware/config.txt.org                                  |
sed 's/device_tree_address=0x100/device_tree_address=0x02008000/'       |
sed 's/device_tree_end=0x8000/#&amp;/'					|
sudo tee $tmp-config 

sudo mv $tmp-config /boot/firmware/config.txt

### stop network device update ###
echo linux-firmware-raspi2 hold |
sudo dpkg --set-selections

### update ###
sudo apt update
sudo apt -y upgrade

### install WiFi tools ###
sudo apt -y install wireless-tools wpasupplicant

sudo reboot

このコードを読むと分かりますが、ファームウェアの自動アップデートを止めていますのでご注意ください。このリポジトリにある他のシェルスクリプトは、ラズパイマウス本の各パートのコードをラズパイにインストールして、各章を飛ばしてしまうためのチート的なものです。

ますとどん

遊んでます。

今のところ謎論理を展開する変なおじさんおばさんがいなくて非常に開放的です。多分、スキル的に彼らがやってくるのは当面先の話でしょう。Twitterでよく絡んでいる人たちも、束の間の自由を楽しんでいるご様子でした。自分が小難しいことをTwitterでたまに言ってしまうのは、変なおじさんおばさんを見てイライラして、そっちの側に回ってしまうという一種の集団ヒステリーなんだなーと反省しました。

 

このサービスについていろいろ評論している人がいますが、もし何かあるなら自然淘汰されるだけなので、ブックメーカーが賭けをしない限り、なんの意味もないと思います。そういう人たちは自分の仕事に集中していないだけなので、気にすることはないと思います。管理者さん頑張れ。

今週末はシェル芸勉強会

今回は募集が早すぎたような気がして、ドタキャンが多い予感がします。どうなることやら。内容は「普通のsed」にしました。普通とは。

寝る。

Pocket
LINEで送る

日記 —Kindle版ラズパイマウス本、確率ロボティクスのjupyter notebook

Pocket
LINEで送る

ここ数日の報告を2点。

Kindle版ラズパイマウス本

出ました。

 

確率ロボティクスのjupyter notebook

MCLにもgraph-based SLAMにもコメントをたくさん入れました。数式もsympyで入れようとしましたが、ごちゃごちゃしたので別紙に書きます。これも真面目にやると時間がかかるのでおおごとになってきました・・・

Pocket
LINEで送る

Jupyter notebookで確率ロボティクスのコードを書いていくプロジェクトを始めた

Pocket
LINEで送る


表題の通りの新プロジェクトを始めました。この前まではプログラミング言語兼シェルのGlueLangを作ってましたが、これは一段落がついてOSCかどこかで発表をするというフェーズに入っています。ユーザがほとんどいませんが、地道に増やして行きたいです。歳をとると(そうでなくても)、やむを得ない理由もないのに手が止まって評論家みたいになっちゃう人たちがいるのは、Facebookで地球マーク持論撒き散らし系を見てるとよく分かるかとは思いますが、自分は死ぬまでそうはならんぞと、一人、誰に頼まれているわけでもなく意気込んでいます。(なんで毒づいているんだろう?)

 

あ、安心してください。ちゃんと研究も履いてますよ!じゃなかったやってますよ!

新プロジェクトでやること

今回やることは、10年前に翻訳したこの本:

のアルゴリズムと、本に掲載されていない新しいアルゴリズムをjupyter notebookで記述することです。ご存知の方も多いはずですが、確率ロボティクス関係のコードの例は@Atsushi_twiさんがMatlabで書いていらっしゃるので、見比べて参考にしていただければと。図が似ちゃってすみません。

目的

  • 講義で使う(予定があるだけでも大学院の後期の講義、とある中部地方の大学での非常勤講師、五月のロボット学会のセミナーと色々)
  • 自分で書いたコードでないと説明が大雑把になるので自分で一通りコードを書く
  • 翻訳本に引き続き日本語のドキュメントを充実してパブリックに晒す

もちろん、最先端ではないのですが、特に日本語話者で基本的なアルゴリズムを知っている人が増えて層が厚くなれば、最先端を目指す人も増えるだろうと考えています。もちろん、自分も早く最先端に追いつきたいのですが、もうちょっと時間がかかりそうですし、教育も重要なのでバランスよく貢献したいと思ってます。

さっそく2つ作った

とりあえずMonte Carlo Localizationgraph-based SLAMを実装しました。リンク先にはコードだけでなく、図も出力されています。jupyter notebookとGitHubの機能はただただ素晴らしいですね。(PCから閲覧しないと、コードや図が見えずにJSONのデータが見えてしまうかもしれません。)

解説はコードの中に書いていく予定(少し書いてありますが、なんとなく英語で書き始めてしまったので日本語にしていきます)ですので、ここでは画像だけ貼ってお茶を濁すことにします。まだ始めて4日目なので、細かい話はご勘弁を。

Monte Carlo Localization

この図は、ロボットがランドマーク(星)の距離と見える向きを測って自己位置推定している様子です。ロボット(赤い矢印)が座標(0,0)の原点からスタートして、ぐるっと円を描いて、今は原点の下あたりにいます。

 

現在の赤い矢印の下に、青い矢印の集団がいますが、この矢印一つ一つはランドマーク観測とデッドレコニング情報から推定されたロボットの候補点(パーティクル)です。灰色の矢印は、デッドレコニングのみで推定したときのパーティクルを比較で表示したもので、青い矢印より拡散して推定がボケているのが分かります。

右下のランドマークに水色の楕円がたくさんあるのは、ロボットのランドマーク計測結果を各パーティクルの位置からプロジェクションしたもので、この楕円がランドマークの位置に近いパーティクルが、次のステップのパーティクルを生成するときに重視されます。

graph-based SLAM

確率ロボティクスになかった(GraphSLAMという似たものはある)ので、新たに説明文を作るには自分で実装するしかなく、このプロジェクトを始めたきっかけになったアルゴリズムです。GraphSLAMとはちょっと違うという認識ですが、どこが違うか(確かデッドレコニングのデータの扱いだったような)はもう一度読まないと思い出せません。解説の文章はこちらにありますが、同様の内容のものが書いたご本人によってアップされているので探してみていただければと。

graph-based SLAMはオフラインの地図生成手法で、ロボットのデッドレコニング情報とランドマーク計測の情報を集めてから、後処理でロボットがたどったパスを求め、そこからランドマークの位置を求めます。図は、上が集めた情報、下が集めた情報からSLAMでパスを求めた結果です。赤の矢印がロボットの真のパス、灰色が推定値で、上の図ではデッドレコニングで求めたパスそのままですが、下では修正されて赤の矢印に近くなっています。なお、ランドマーク計測では、ロボットからの距離と見える向きの他に、ランドマークにも向きがあって、ロボットからそれが観測できるという前提を置いています。ランドマークは互いに識別可能という前提も置いています。

 

水色の楕円は二箇所から同じランドマークを観測したときに、一つの位置からもう一方の位置がどこに推定されて、その信頼性(共分散行列)がどのように広がっているかを示しています。要はこれらの楕円を推定されるパス上に寄せていくことで推定を進めていくのがこのアルゴリズムです。ピンク色の線は推定位置から見えたランドマークの位置を指しており、これも推定が進むと正解の位置に揃ってきます。

 

なお、センサの精度を上げてやるともっとドンピシャで合ってかっこ良いのですが、さすがに都合が良すぎるのでちょっと下げてやってます。

 

とりあえず5月の講演に向けてちまちま作っていく所存。

Pocket
LINEで送る

「Raspberry Piで学ぶ ROSロボット入門」を安価に楽しむ方法

Pocket
LINEで送る

先月30日に発売された「Raspberry Piで学ぶ ROSロボット入門」ですが、やっぱりロボットが高くて手が出しにくいという反応をいただいておりますので、なくても楽しめるように、いくつかロボットなしのプランを提示します。ついでに本書の内容もどんなものか匂わせます。

もちろん、実機があるのがベストです。

Travis CIとの格闘を楽しむ

本書はロボットを動かすための本ですが、テストがたくさん盛り込んであり、Travis CIも裏の操作対象のような位置付けになっています。また、ロボットがなくても、テストが通るかどうかで、コードが正しいかどうかは、完全ではありませんがだいたい分かります。ということで、勉強だけならTravis CIでテストを通すことを目標にしてコードを書くことができます。

また、講義では、ロボットを1人1台ではなく、教室に数台だけにしておき、テストを通した人から実機を試すという運用も考えられます。これはテストを扱っているからこそ可能になることです。また、私も職業柄、当然講義を持っておりますので、ちゃんと講義や実習が成立するように考えて書いておりますです。

実機を作る

これはかえってコストがかかるかもしれませんが、少しずつ部品を揃えて試していくこともできます。ハードウェアの使用はこちらに公開されていますので、挑戦してみるのも良いかもしれません。

シミュレータと接続

最後、ラズパイマウスのシミュレータで試すという方法もあります。ただ、本書のコードとシミュレータのつなぎこみには少し手間がかかります。少しだけ付録で説明しましたが、ちょっと本書を読み進めないと難しいかと。

ということで、シミュレータの作者にどんどんissueを投げていけば、そのうち答えが出てくるものと予想されます(ひどい)。

また、シミュレータは、入出力口を全てROSのインタフェースで持っています。が、実機はデバイスファイルがインタフェースなので、そういう点ではシミュレータは不完全です。ここをデバイスファイル(もちろん普通のファイルでも可)でブリッジできればシミュレータとして完全なのですが・・・。この点は気になっているところなので、こちらでも働きかけを続けます。

おわりに

3つ挙げたうちの後ろの2つは大変ですが、最初の項目のように、本書は一つのロボットを多人数でシェアしても大丈夫な構成になっています。また、ロボットは持っている人のところで動かして、あとはテスト環境でソフトウェアを書くということもできるようになっています。

ということで、ぜひ一読いただければと。

Pocket
LINEで送る

GlueLangのwhere句の実装

Pocket
LINEで送る

 GlueLangは、その場で使うファイルを次のような書き方で作れます。Haskellから拝借しました。bashの$()がコマンドの引数にあると綺麗に見えないので、whereの中にそういう細かい処理は押し込んでしまおうという意図です。

import PATH

#passwdファイルの一番下のユーザの名前でpasswdファイルをgrepする
grep re '/etc/passwd'
  where
    str re = tail -n 1 '/etc/passwd' >>= awk '-F:' '{print $1}'

bashだとこうなります。

grep $( tail -n 1 '/etc/passwd' | awk '-F:' '{print $1}' ) '/etc/passwd'

 これの実装をするにはスコープを真面目に設計・実装する必要がありますが、GlueLangはシェルなので、基本「スコープはforkしたときに持っていた情報の範囲」で良く、whereのためだけにスコープを作ることになります。これがこれまでグダグダだったので、昨夜遅くコソコソと直してました。具体的には、

  • 変数に、どのジョブに属するのかIDをつける
  • 各要素が解釈されたときに、要素のインスタンスにこれまで分岐してきたジョブのリストを渡す
  • 変数を探すときに、そのリストの逆向きたどる

という処理を加えました。リストを解釈された要素全部に渡すので無駄なのと、ジョブが消えても変数が残ったままになっているという状況ですが、あとから改善します。

Pocket
LINEで送る

GlueLangに標準入力を読みながら実行するループを実装

Pocket
LINEで送る

昨日の続きです。今日は大学で卒業に関するイベント等々があって酔っ払って帰ってきましたが、勢いで開発を進めました。

今日は、bashの次のような処理をGlueLangに実装しました。

###こんなスクリプト###
$ cat hoge.bash 
#!/bin/bash

seq 1 3 |
while read a ; do
	echo "@" $a
done
###こんな出力###
$ ./hoge.bash
@ 1
@ 2
@ 3

GlueLangだと次のようになります。標準入力から1行ごとに配列argvに文字列が読み込まれ、foreachの下に書いた処理が繰り返されます。

###こんなスクリプト###
$ cat hoge.glue 
import PATH

seq 1 3 >>= foreach
  echo '@' argv[1]
###こんな出力###
$ glue ./hoge.glue 
@ 1
@ 2
@ 3

こんな感じです。寝る。

Pocket
LINEで送る

GlueLangにループを実装

Pocket
LINEで送る

 帰省中に少し時間があったので、GlueLangにループを実装しました。次のように使います。この例は、dateにUnix時刻を吐かせて、5で割り切れる数になったらループを抜ける処理です。testコマンドが0でない終了ステータスを返したのを受けてループが終わって最終行のechoが実行されます。

$ cat hoge.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}'
  echo t
  test t -ne 0
  sleep 1

echo 'end'

 実行すると、ちゃんと動きます。これはMacで動かしましたが同じコードでLinuxでも動きます。

$ glue ./hoge.glue 
1
2
3
4
0
end

shのwhileのように書くには

 shやbashのように、 while <コマンド> ; do <処理> ; done と書く場合、つまりコマンドの終了ステータスで処理を実行するかしないかを決めるときは、1段ネストが深くなりますが、次のように記述できます。

$ cat hoge2.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}' #この行と
  test t -ne 0 >> do                        #この行のdoの前までが条件
    echo t                                  #doのあとが繰り返したい処理
    sleep 1

echo 'end'

 ネストが2段になりますが、shやbashのwhileよりも長く条件となるコマンドが書けます。だいたい、while hogehoge ; do …という書き方が、hogehogeという部分をコマンドだと気づかない初心者を量産しており悪い影響を与えているので、踏襲するわけにはいけません。

文法エラーの時に止める

で、シェルでループを作るとCtrl+Cやスクリプトにエラーが思うように止まらない場合がありますが、GlueLangでは止められるように工夫をしました。次の例は、コマンドが見つからない時にすぐにループを止めて、最終行の echo ‘end’ が実行されないことを確かめる例です。

$ cat hoge3.glue 
import PATH

loop
  str t = date '+%s' >>= awk '{print $1%5}'
  eho t     #ここでエラーが起こって処理全体が止まる
  sleep 1
  test t -ne 0

echo 'end'  #これは実行されない

 GlueLangでは(まだ実装が中途半端ですが)「コマンドが実行されて返ってくる終了ステータス」と「コマンドが見つからない、あるいはGlueLangのスクリプト自体が出すエラー」を区別することにしました。技術的には可能ですし、これは普通のシェルよりもエラーへの対応がかなりスマートになるのではないかと考えています。

$ glue ./hoge3.glue 

Parse error at line 2, char 1
	line2: eho t
	       ^

	Command eho not exist
	
	process_level 1
	exit_status 2
	pid 30839

	glue exit_status: 2

Execution error at line 3, char 1
	line3: loop
	       ^
	line4:   str t = date '+%s' >>= awk '{print $1%5}'
	line5:   eho t
	line6:   sleep 1
	line7:   test t -ne 0
	line8: 

	Command error
	
	process_level 0
	exit_status 2
	pid 30837
###echo 'end'が実行されずに終わる###

 ただ、現状で先ほどのように2段にネストした場合、止まらないのでまた来週末あたり改良します。また、readも実装しないといけません・・・。

Pocket
LINEで送る