【D言語】Voldemort Typeについて【名前を呼んではいけないあの型】
D言語erのみなさん、あけましておめでとうございます。
今回は、ニュースグループでよく目にするけれど、日本語の資料は全くないVoldemort Typeについて、語っていきます。 大丈夫です、ハリー・ポッターのヴォルデモートであってます。
例えば、動的配列からInputRangeを作成する関数を作ってみます。
import std.stdio;
struct ArrayToInputRange(E)
{
E[] array;
this(E[] array)
{
this.array = array;
}
@property
E front()
{
return array[0];
}
void popFront()
{
array = array[1..$];
}
@property
bool empty()
{
return array.length == 0;
}
}
auto toInputRange(E)(E[] array)
{
return ArrayToInputRange!E(array);
}
void main()
{
auto range = [1, 2, 3, 4].toInputRange();
range.writeln(); // [1, 2, 3, 4]
}
できました。簡単ですね。 簡単なのですが、一つ問題があります。それは、
Rangeを作るためだけに作ったArrayToInputRangeが、いろんな場所から見えちゃう!!
という点です。
上のソースコードのmain関数の中身を見てみてください。 ArrayToInputRangeなんてどこにも出てきてませんね。 D言語にはautoがあるので、わざわざArrayToInputRange!intなんて書く必要がありません。
toInputRange以外ではArrayToInputRangeは使われるはずがありません。 それにも関わらず、ArrayToInputRangeは存在してしまうので、名前空間を汚していきます。 つまり、カプセル化に失敗しているのです。
@youxkei と思うじゃん?
— Codelogyさん (@codelogy) 1月 4, 2013
確かに、モジュールが違えば、privateで隠すことができます。 が、同じモジュール内では、privateは効果を発揮しないので、完全にカプセル化できません。
さて、こんな感じに書いてみたらどうでしょう?
import std.stdio;
auto toInputRange(E)(E[] array)
{
struct ArrayToInputRange
{
E[] array;
this(E[] array)
{
this.array = array;
}
@property
E front()
{
return array[0];
}
void popFront()
{
array = array[1..$];
}
@property
bool empty()
{
return array.length == 0;
}
}
return ArrayToInputRange(array);
}
void main()
{
// toInputRange.ArrayToInputRange <ー これは出来ない!!
auto range = [1, 2, 3, 4].toInputRange();
range.writeln(); // [1, 2, 3, 4]
}
なにか興味深いことが起きていますね!! ArrayToInputRangeがtoInputRangeのスコープ内に移動したおかげで、toInputRangeの外からは、その名前を呼べなくなっています。 名前を呼ぶことができない・・・そう、これこそがVoldemort Typeです。
上のコードは、ArrayToInputRangeをVoldemort Typeにした(つまりスコープを関数内に移した)ことによって、カプセル化に成功しています!!
「名前を呼べないと、使う時に困るんじゃね?」 と思われる人もいるかもしれません。
名前が呼べないなら、autoを使えばいいじゃない
— Codelogyさん (@codelogy) 1月 4, 2013
つまり、そういうことです。 autoを使えば、関数のスコープの外から型の名前を呼べなくても、問題なく使うことができます。
今回は、名前を呼んではいけないあの型、つまりVoldemort Typeについて語ってきました。 「名前を呼んではいけないあの型」よりも、「名前を呼ぶことができないあの型」の方が正確ですね(^_^;) これの応用として、Voldemort FunctionやVoldemort Templateなどが考えられます。 皆さんも、「絶対に名前空間を汚したくない!!」というような時に、ぜひ使ってみてください。
担当:美馬(しかし、Voldemort Typeとは、素晴らしいネーミングセンス!)