fluorite-7　日本語チュートリアル　Part 8　スクリプトファイル


[チュートリアルトップ](https://qiita.com/MirrgieRiana/items/a0906c72ebfb46693ab5)

[←前回](https://qiita.com/MirrgieRiana/items/fbe470dd913cbe0f501d)　[次回→](https://qiita.com/MirrgieRiana/items/e35826c75c3d77fe9146)

このパートでは、ソースコードのスクリプトファイル化について取り扱います。

# レッスン1　ソースファイル

これまで、fluorite-7言語のソースコードはすべてコンソール上で`fl7`コマンドに直接入力することで実行されてきました。

```bash:
$ fl7 '1 .. 4 | _ ^ 2'
1
4
9
16
```

しかし、コードが長くなるとファイルに保存してファイルを指定して呼び出したくなります。

`fluorite7`は、ファイルを指定するとそのファイルを読み出して実行するコマンドです。

```bash:
$ echo -e '1 .. 4 | _ ^ 2' | tee tmp.fl7
1 .. 4 | _ ^ 2
$ fluorite7 tmp.fl7
1
4
9
16
```

```perl:tmp.fl7
1 .. 4 | _ ^ 2
```

このようなファイルを**ソースファイル**と呼びます。
fluorite-7言語のソースファイルは`.fl7`の拡張子を持つことが推奨されます。

----

一方、`fl7`に直接入力するソースコードは**ワンライナー**と呼びます。

# レッスン2　スペースと改行

fluorite-7では、ソースコード中のほとんどすべての場所に自由に半角空白・タブ・改行を自由に入れることができます。
改行は原則として特別な意味を持たず、空白と同じです。

```bash:
$ echo -e '1    ..    4 | \n\t_ \n\n^ 2' | tee tmp.fl7
1    ..    4 |
        _

^ 2
$ fluorite7 tmp.fl7
1
4
9
16
```

```perl:tmp.fl7
1    ..    4 |
        _

^ 2
```

# レッスン3　コメント

`#` `//`から改行までの間は**コメント**です。
コメントは空白を置ける場所であれば基本的にどこでも置くことができ、どれだけ書いても単に無視されます。

```bash:
$ echo -e '# コメント\n// コメント\n100' | tee tmp.fl7
# コメント
// コメント
100
$ fluorite7 tmp.fl7
100
```

```perl:tmp.fl7
# コメント
// コメント
100
```

ただし、長さ演算子`$#`のように、演算子の一部分になっている`#`については、コメントとしては扱われません。

# レッスン4　ブロックコメント

`/*`と`*/`で挟まれた部分はブロックレベルのコメント（**ブロックコメント**）です。

```bash:
$ echo -e '/* コメント\n コメント\n*/100' | tee tmp.fl7
/* コメント
 コメント
*/100
$ fluorite7 tmp.fl7
100
```

```perl:tmp.fl7
/* コメント
 コメント
*/100
```

ブロックコメントには、`*/`以外の文字なら改行を含むすべての文字を書くことができます。

----

`/+`と`+/`で挟まれた部分もブロックコメントですが、こちらはコメントをネスト出来ます。
`/+`の後に`/+`が現れた場合、`+/`が2回現れるまでの間をコメントとして無視します。

```bash:
$ fl7 '/+ /+ /* +/ */ +/ 100'
100
```

# レッスン5　スクリプトファイル

ソースファイルの1行目に`#!/usr/bin/env fluorite7`と記述し実効権限を与えると、Linuxの機能により、そのまま実行できるようになります。
このようなソースファイルを**スクリプトファイル**と呼びます。

```bash:
$ echo -e '#!/usr/bin/env fluorite7\n1 .. 4' | tee tmp.fl7
#!/usr/bin/env fluorite7
1 .. 4
$ chmod +x tmp.fl7
$ ./tmp.fl7
1
2
3
4
```

```perl:tmp.fl7
#!/usr/bin/env fluorite7
1 .. 4
```

# レッスン6　コマンドライン引数

ソースコードがワンライナー形式であっても、ソースファイル形式であっても、スクリプトファイル形式であっても、コマンドライン引数を取ることができます。
コマンドライン引数には`ARGV`という組みこみ定数でアクセスできます。
`ARGV`はコマンドライン引数が順番に格納された配列です。

----

ワンライナーにコマンドライン引数を与えるには、`fl7`コマンドに対して、ソースコードに続けて引数を指定します。

```bash:
$ fl7 'ARGV[]' a a "a a"
a
a
a a
```

----

ソースファイルにコマンドライン引数を与えるには、`fluorite7`コマンドに対して、ソースファイルに続けて引数を指定します。

```bash:
$ echo -e 'ARGV[]' | tee tmp.fl7
ARGV[]
$ fluorite7 tmp.fl7 a a "a a"
a
a
a a
```

```perl:tmp.fl7
ARGV[]
```

----

スクリプトファイルにコマンドライン引数を与えるには、スクリプトの呼び出しに対して引数を指定します。

```bash:
$ echo -e '#!/usr/bin/env fluorite7\nARGV[]' | tee tmp.fl7
#!/usr/bin/env fluorite7
ARGV[]
$ chmod +x tmp.fl7
$ ./tmp.fl7 a a "a a"
a
a
a a
```

```perl:tmp.fl7
#!/usr/bin/env fluorite7
ARGV[]
```

# レッスン7　環境変数の取得

「`ENV.`識別子」もしくは「`ENV[`文字列`]`」で、識別子が表す環境変数を取得します。

```bash:
$ AAA="abcde" fl7 'ENV.AAA'
abcde

$ AAA="abcde" fl7 'ENV["AAA"]'
abcde
```

組み込み定数`ENV`は、後に紹介する「オブジェクト」という種類の値を持ちます。

# レッスン8　REQUIRE関数・USE関数

`REQUIRE`は、文字列で指定した外部ファイルをfluorite-7ソースファイルとして実行し、結果の値を得る組み込みの関数です。

```bash:
$ echo -e '1 .. 4' | tee tmp.fl7
1 .. 4
$ fl7 'REQUIRE("tmp.fl7")'
1
2
3
4
```

```perl:tmp.fl7
1 .. 4
```

----

`USE`関数も同様ですが、こちらは一度読み込んだファイルに対しては結果を覚えておいて、それを使いまわします。

```bash:
$ echo -e '1 .. 4' | tee tmp.fl7
1 .. 4
$ fl7 'USE("tmp.fl7"), USE("tmp.fl7")'
1
2
3
4
1
2
3
4
```

```perl:tmp.fl7
1 .. 4
```

常に同じ結果しか返さないソースファイルではちゃんと結果が再利用されているかわかりませんね。

`RAND`関数は0以上1未満の乱数を返す関数です。
評価する度に新たな乱数を生成して返します。
数回実行した程度では全く同じ結果は得られないと思ってよいです。

```bash:
$ fl7 '1 .. 4 | RAND()'
0.9560447890649331
0.4559649194523645
0.3865209695764489
0.23556658453588875
```

これを使用したソースファイルを`REQUIRE`および`USE`によってそれぞれ2回呼び出してみます。

```bash:
$ echo -e 'RAND()' | tee tmp.fl7
RAND()
$ fl7 'REQUIRE("tmp.fl7"), REQUIRE("tmp.fl7")'
0.18784862104533007
0.8350319470723166
$ fl7 'USE("tmp.fl7"), USE("tmp.fl7")'
0.06544536675032453
0.06544536675032453
```

```perl:tmp.fl7
RAND()
```

見事同じ結果が得られました。

`USE`は、fluorite-7において最もメジャーなファイル分割手段です。

# レッスン9　EVAL関数

`EVAL`は、与えた文字列をfluorite-7ソースコードとして評価し、結果を返す関数です。

```bash:
$ fl7 'EVAL("1 .. 4")'
1
2
3
4
```

コードを文字列で与えられるので、ソースコードをコマンドライン引数から与えたりもできます。

```bash:
$ fl7 'EVAL(ARGV[0])' '1 .. 4'
1
2
3
4
```

fluorite-7のソースコードは外部コマンドの呼び出しを含む様々な処理を実行できるため、使う場所を選ばなければ当然危ないです。

# まとめ

- fluorite-7ソースコードを格納したソースファイルは、`fluorite7`コマンドで実行する。
- ソースファイルの拡張子は`.fl7`を推奨。
- 改行は原則として特別な意味を持たない。
- コメントは`#` `/` `/*` `*/` `/+` `+/`が使える。
- `/+` `+/`は入れ子にできる。
- `ARGV`にコマンドライン引数の配列がやってくる。
- `ENV[string]`で環境変数が得られる。
- `USE`関数で外部ソースファイルを実行し、結果を得る。
- `EVAL`関数で文字列を実行し、結果を得る。

# Part 9

[次回→](https://qiita.com/MirrgieRiana/items/e35826c75c3d77fe9146)