LoginSignup
0
0

More than 5 years have passed since last update.

必要悪の preserving

Last updated at Posted at 2013-06-13

Boo のスコープ

Boo には言語コアな機能として、(メソッド内などで)ローカルスコープを導入する方法がありません。

例えば、C++やJavaなんて方面の言語は { } を使って、次のようにローカルスコープを導入できます。

int a = 5;
if ... {
   int a = 3;  // シャドウイング。外側の a とは違う。
   int b = 9;
   cout << a << endl; // 3
}
cout << a << endl;  // 5
// cout << b << endl;  // コンパイルエラー。b は if の内側の変数。

Boo は、上記のC++コードを真似しても結果が違います。

a as int = 5
if ...:
    # a as int = 3   # コンパイルエラー... ;_;
    a = 3
    b as int = 9
    print a   # 3
print a   # 3
print b   # 9 です。内側も外側もないです。

そこで、Boo には preserving というローカルスコープ「っぽいもの」を導入するマクロがあります。
これがスゲーかっこ悪い。

a as int = 5
preserving a:   # このブロック抜けたら a の値が復帰する。
    # a as int = 3   # これはやっぱりコンパイルエラー
    a = 3
    print a   # 3
print a   # 5

超カッコ悪いです。なんか、preserving というマクロの後に保存する変数名書いたりするのが、php の無名関数で use とかわざわざ書かせているみたいです。

まぁ、ブロックにスコープ機能が無いので、次のような場合に1行得する、とかイマイチお得に感じられないメリットもあります。

# if で分岐して変数 a に値設定。
# この行に a as int のような宣言が必要無い、という微妙なお得度。
if ....:
    a = 5  # Boo は代入が宣言を兼ねられる。これもばっちいですね。
else:
    a = 3
print a  # 分岐処理の結果

preserving の正体

preserving は次のマクロです。もう想像通り。ソースは Boo 処理系の src/Boo.Lang.Extensions/Macros/PreservingMacro.boo から。

macro preserving:
    restoration = Block()    # 指定した変数を復帰する代入文を入れるブロック。
    for arg in preserving.Arguments:
        # テンポラリ変数を作って、指定した変数値を保存するコード展開
        temp = ReferenceExpression(Context.GetUniqueName("preserving"))
        yield [| $temp = $arg |]
        # 復帰ブロックに、保存した値を再代入するコード追加。
        restoration.Add([| $arg = $temp |])     
    yield [|
        try:
            $(preserving.Body)   # preserving の本体
        ensure:
            $restoration   # 本体の処理おわったら、復帰ブロック実行。
    |]

まぁ、この方法を拡張して、preserving のブロックをネストメソッド(Boo はメソッドの中でメソッドを定義できます)として定義すれば、それなりにちゃんとしたスコープを導入することはできます..。

でも、初めっからちゃんとコアな機能としてほしいよね...。

結論

Boo って結構汚い言語です。それが Boo クオリティ。

といいながら、この preserving はさすがに使ったことありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0