Top/マニュアル/文法/3.値と変数
  トップページへ   [ 一覧 | 検索 | 最終更新 ]   [ 差分 | 履歴 | 凍結 ]

値と変数

即値

文が扱える値は整数、実数、文字列の3種類です。

整数(int)

符号付き64bit整数です。 (Tc566-1で拡張、その前は32bit)
10進数値はそのまま記述します。
先頭に"0b"を付加することにより、2進数値を記述できます。
先頭に"0x"を付加することにより、16進数値を記述できます。 以下の関数int10は整数10を返します。3つの記述はいずれも10進数では10だからです。

int10
{
    10
    0b1010
    0xa
}

実数(double)

符号付き64bit浮動小数点数です。小数点以下の桁がある場合や、精度が落ちてもいいので非常に巨大な数値を扱いたい場合はこれを使用します。 整数との区別は小数点の有無です。文は数値に小数点を見つけると、これを実数として取り扱います。 例えば

Test
{
    3/4*100
}

とすると結果は75ではなく0になってしまいます。これは3/4を評価した時intとして解釈してしまい、小数点以下が切り捨てられてしまうためです。(演算子は左から順に評価されます)意図した動作にするには

Test
{
    3.0/4*100
}

とする必要があります。これは3.0を評価した時点でdouble型として解釈するためです。(double型のため結果は75ではなく75.000000となります。整数にしたい場合はTOINT関数を使ってください) 変数の演算でこれを行いたいときは宣言時に実数を代入するか、TOREAL関数を用いる必要があります。

Test
{
  _A = 3
  _B = 4
  TOREAL(_A)/_B*100
    
}

文字列

ダブルクォート(")で囲まれた値は文字列です。 「/」を文末に書くと改行を含む文字列を記述することができます。

"こん\n/
なかんじに\n/
書いてもOK\n/"

後述するヒアドキュメントを用いても改行を含む文字列を書けます。 また、さくらスクリプトは文字列として記述しないと動作しません。

Tc569-8以前のバージョンでは、文字列の中にダブルクォートが含まれてはいけません。
Tc569-8以降のバージョンでは、ダブルクォートを2回続けて書くことで、文字列内にダブルクォートを追加することができます。

"1""2"

と書くと

1"2

という文字列を定義したことになります。

文字列(展開なし)

シングルクォート(')で囲まれた値は、展開されない単純な文字列です。
文では文字列中に変数や関数を埋め込むことが出来ますが、これが展開されるのはダブルクォートで囲まれた文字列のみです。

Tc569-8以前のバージョンでは、文字列の中にシングルクォートが含まれてはいけません。
Tc569-8以降のバージョンでは、シングルクォートを2回続けて書くことで、文字列内にシングルクォートを追加することができます。

'1''2'

と書くと

1'2

という文字列を定義したことになります。

あまり複雑な使い方をすると後で見にくくなるのでおすすめしませんが、同時に使う例として、

'1''2"3'
"1'2""3"

はいずれも、

1'2"3

という文字列を定義したのと同じになります。

ヒアドキュメント

「ヒアドキュメント」とは、複数行書ける文字列即値です。
Tc535-1から使用可能になりました。

<<"
行1
行2
">>

で展開あり文字列、

<<'
行1
行2
'>>

で展開無し文字列になります。
ヒアドキュメントの前や後にいろいろな式を書けますが、辞書ファイル内のみのサポートで、EVALしてもエラーになります。

変数

変数は値を格納するための領域です。
ひとつの変数には、

  • 整数、実数、文字列
  • 要素ごとに上記のいずれかを格納可能な汎用配列

を格納することができます。 名前は以下の禁止条項に抵触しない限りは自由につけることができます。

  • 数字0~9で始まる。
  • 以下の文字を含む。
    空白 ! " # $ % & ( ) * + , - / : ; < = > ? @ [ ] ` { | } 
  • 予約語と完全に一致する。
  • 関数名と完全に一致する。

値の格納(代入)は代入演算子 = で行ないます。内容を出力するには、関数と同様にその名前を書きます。

request
{
    str = "こんにちは"
    
    str
}

上は単純な例で、変数strに文字列を格納し、そのまま出力しています。

まだ値が代入されていない変数は、「未定義型」という特殊な型となります。
「何も出力しない」ではないことに注意してください。

request
{
    "Hello World"
    i
}

この場合、i は存在しないため、「未定義型」となります。
「未定義型」は、数値との演算では0、文字列との演算では '' (空っぽの文字列)扱いとなります。上記の例では、この「未定義型」と"Hello World"という文字列のどちらかが1/2の確率で返されます。

変数のスコープと寿命

変数はスコープ(有効範囲)の違いによって2種類存在します。

  • グローバル変数
    すべての関数で共通に使用できる変数。寿命は(ERASEVAR関数で消去されない限り)永遠。
  • ローカル変数
    現在の{ }内、およびそれより深い入れ子階層のみで使用できる変数。寿命は該当する{ }を抜けるところまで。

両者を区別するのは変数の名前です。変数名の先頭がアンダースコア("_")の変数は、ローカル変数として扱われます。 「必要な範囲だけで有効な変数」であるローカル変数をうまく利用することで、プログラムの見通しが良くなります。

request
{
    _i = "3*2は"
    
    _j = multi(3)
    
    _i + _j + "です"
}

multi
{
    _i = _argv[0]
    _i * 2
}

requestとmultiが同じ名前の変数 _i を使っていますが、それらはまったく別物として扱われます。お互いの値を破壊することはありません。 関数の引数を扱う変数_argcと_argvも実はローカル変数であることに気付かれたかと思います。
これらもまた関数ごとに別の値を格納しますので、 ローカル変数になっているわけです。

ローカル変数が「現在の関数内で使用可能な変数」ではなく、「現在の{ }内、およびそれより深い入れ子階層のみで使用できる変数」であることには注意してください。

request
{
    {
        _str = "Hello World"
    }

    _str
}

このプログラムは期待通りには動作しません。
_strは{ }内のみで有効ですから、出力を取り出そうとしている位置では消えてしまっています。
したがって、この関数requestは空の文字列を出力します。 グローバル変数とローカル変数の違いはもうひとつあります。寿命です。
ローカル変数は上で見たとおり、変数を使用している{ }から外れると消えてしまいます。
対してグローバル変数はどこでも使用可能、さらにunloadでその値はファイルへ自動的に保存され、loadで復元されるようになっています。

グローバル変数を削除するにはERASEVAR関数を使う必要があります。また、その性質上グローバル変数の初期化は起動時に最初に実行される関数(OnBootなど)で行うことを推奨します。