GlueLangのif文相当の処理をガラッと変えてみた
Sat Mar 21 22:45:26 JST 2015 (modified: Fri Sep 29 21:38:45 JST 2017)
views: 1577, keywords:サブシェル,GlueLang,OR記号,寝る,研究,グルー言語を作る この記事は最終更新日が7年以上前のものです。
今日は息抜きにGlueLangをいじっておりました。といっても言語の開発なので、処理系のバグと、スクリプトのバグの両方に気をつけなければならず、なかなかイライラするものですが・・・
機能追加1: 複合コマンド
今までGlueにはカッコがなかったのですが、bash同様にコマンドをまとめられるようにしました。次の例は2つのechoの出力をrevに渡しているものです。
uedambp:SRC ueda$ cat hoge
#!/usr/local/bin/glue
import PATH
{
echo 'abc'
echo 'def'
} >>= rev
uedambp:SRC ueda$ ./hoge
cba
fed
機能追加2: OR
もう一つ、ORを表す「!>」という記号を作ってみました。もともとAND演算子「>>」がありますが、「!>」はその逆で、左側のコマンドがエラーを起こしたときだけ右側以降のコマンドが実行されます。例を示します。最初のecho 'a'とfalseの右側のecho 'b'だけ実行されます。echo 'b'が成功してしまうので、echo 'c'は実行されません。
uedambp:SRC ueda$ cat hoge
#!/usr/local/bin/glue
import PATH
echo 'a' >> false !> echo 'b' !> echo 'c'
uedambp:SRC ueda$ ./hoge
a
b
diffやgrepのように正常でも終了ステータス1を返してくるコマンドでスクリプトが止まらないようにする用途にも使えます。
uedambp:GlueLang ueda$ cat hoge
#!/usr/local/bin/glue
import PATH
file a = seq 1 3
file b = seq 1 2
diff a b !> true
uedambp:GlueLang ueda$ ./hoge
3d2
< 3
ifをわざわざ作らなくてもよくなった
んで面白いことに、上の2つの拡張のお陰でif文が不要になったので思い切って削除しました。今までは、
? false
echo 'hoge'| true
echo 'foo'| otherwise
echo 'bar'
という書き方にしていましたが複合コマンドとORで、
#!/usr/local/bin/glue
import PATH
{
false
echo 'hoge'!> {
}
echo 'foo'!> {
}
echo 'bar' }
でif文みたいになります。実行すると、最初のカッコでfalseがエラーを出すので、二番目のカッコの中に処理が移ります。最後のカッコは2番目のカッコが正常終了するので実行されません。
uedambp:SRC ueda$ ./hoge
foo
カッコ内でコマンドがエラーを起こすと次のカッコに処理が移ります。カッコ内で全コマンドが正常終了すれば、!>でつながっている後ろのカッコ内は実行されません。
少し癖があるのは、{}内のコマンド全てがif文の条件判定として扱われてしまうことでしょうか。そして、if文でエラーが起きてもそれまでの出力は出てしまいます。
uedambp:SRC ueda$ cat hoge
#!/usr/local/bin/glue
import PATH
file x = {
echo 'aaa'
false
echo 'bbb'
> {
} !echo 'ccc'
}
cat x
###実行するとaaaもファイルに保存されてしまう###
uedambp:SRC ueda$ ./hoge
aaa
ccc
これを回避したい場合は、こんな書き方をするんでしょうか。もうちょっとうまい書き方があるかもしれません。
uedambp:SRC ueda$ cat hoge
#!/usr/local/bin/glue
import PATH
file x = {
file y = echo 'aaa' >> false
cat y
echo 'bbb'
> {
} !echo 'ccc'
}
cat x
uedambp:SRC ueda$ ./hoge
ccc
眠いので寝る。