menu
書いてる野郎
orebike@gmail.com
シェルスクリプト自体には名前空間というモノは無い?のかよくわからんがちょっと調べても出てこない。
しかし関数スコープはあるので、試しにやってみたらできたので一応メモ。
JSのように関数スコープをこのように使う
hoge1 () { hoge2 () { echo "hoge1-2" } }
このように関数を入れ子にすると hoge2 にはアクセス不能になって呼び出しがガードされる。 これをどのように使うかというと、まず hoge1 を実行してやって hoge2 の定義が出来上がったところで、hoge2 を呼び出すというスタイルになる。
hoge1;hoge2 # => hoge1-2
セミコロンは単なるコマンドのセパレータで続きのコマンドを1行に書く場合に使うが、これが名前空間の階層区切りに見えるので見栄えもよい。
シェルスクリプトは関数の再定義を許してくれているので、
このような書き方ができる。hoge2 が被っていても毎回再定義しているのでセミコロン続きで書けば同名関数を使い分けられるのだ。
hoge1 () { hoge2 () { echo "hoge1-2" } } hoge3 () { hoge2 () { echo "hoge3-2" } } hoge1;hoge2 # => hoge1-2 hoge3;hoge2 # => hoge3-2
これ便利じゃないかな。 あんまり事例が無いのだけど・・・間違った使い方なのか?
これの欠点は名前空間が切れるといっても他を毎度汚染しながら空間を展開するので、既存のものをぶっ壊す危険性が高いということだな。 つまり、一旦この形式を使い始めたら、全部この形式にしないといかんという宿命
これをメタプログラミングで解消きるかもしれんと
hoge1 () { local prefix='abcdefg' eval " ${prefix}_hoge2 () { echo \"hoge1-2\" } " ${prefix}_$1 $2 $3 $4 $5 } hoge3 () { local prefix='hijklmn' eval " ${prefix}_hoge2 () { echo \"hoge3-2\" } " ${prefix}_$1 $2 $3 $4 $5 } hoge1 hoge2 hoge3 hoge2
このように実行可能になる。内部で関数名を動的生成しているので prefix が十分ランダムで長いならば衝突することは無い。