VB.NETイミディエイトウィンドウで記号プログラミング

masa
2010-12-14

こんにちは masa (@masa141421356)です。
竹迫さんのPythonのネタを見てVB.NETでも "saru"を記号だけで出力できるつぶやいたところ
意外と反響があったので記事を書いてみました。よろしくおねがいします。

1.VB.NETで記号プログラミングをするには

VB.NETは言語仕様上普通の方法では記号だけでプログラムを記述する方法がありません。

しかし、VB.NETのイミディエイトウィンドには古いBASICでPRINT文のエイリアスとして用意されていた

? expression

が今でも

Debug.Print(expression)

のエイリアスに形を変えて生き残っているので、これを使って記号だけでコードを実行させることにします。

2.記号だけで作成できるリテラル

VB.NETの構文では記号だけを使って記述できるリテラルは文字列だけなので、それを使って何とかして英数字
を作る方法を考えます。

3.&演算子を活用しよう

&演算子は文字列と文字列ではない値の組み合わせの場合は、自動的に一方の値を文字列へ変換します。

つまり、

?"" & (式)

?(式).ToString()

の代わりに使用することが可能です。

4.Booleanを文字列に変換しよう

文字列と文字列の比較の結果はBooleanになるので、これを利用して値の文字列表現を得ることが出来ます

""&(""="") → "" & True → "True"
""&("">"") → "" & False → "False"
5.数字を使わずに数値を生成する

+ - * / ^ 等の数値演算の演算子と Boolean を組み合わせて使うと True は -1, False は 0
として計算が行われるので、これを使用していろいろな数値を生成することが可能です。

?-("">"") → 0
?-(""="") → 1
?-(""="")-(""="") → 2

生成した数値を "" と&演算子で結合することで、"0"~"9"の数字が生成できます。

6.文字列の任意の位置の文字を切り出す
文字列(整数)

を使うと

文字列.charAt(整数)

と同じ様に指定位置の文字を切り出すことが可能なので、これを使って

?(""&("">""))(-(""="")-(""="")-(""=""))
→ ("" & False)(-True-True-True)
→ "False"(3) → "s"c

の様にして "True", "False" に含まれる "a", "e", "F", "l", "r", "s", "T", "u" を切り出すことが出来ます

7."saru"を作ってみよう

ここまで説明した内容を組み合わせると "saru" を作ることが可能です。

"saru" = "False"(3) & "False"(1) & "True"(1) & "True"(2)

なので

?(""&("">""))(-(""="")-(""="")-(""=""))&(""&("">""))(-(""=""))&(""&(""=""))(-(""=""))&(""&(""=""))(-(""="")-(""=""))
→ "saru"

となります。

8.応用編:特殊な数値の文字列表現を使う

0/0 が NaN になることを利用して

?("" & ((""="")/(""="")))(-("">""))
→ "N"

で "N" を生成することが可能です。また、大きな数値の文字列表現が指数表示になることを利用すると "E" も生成することが可能です。

1/0 の文字列表現から "Infinitiy" が取れそうなのですが、残念ながら無限大の文字列表現は "∞"
になってしまうので英数字の取り出しには使用できません。

9.まとめ
  • イミディエイトウィンドウは?が使えるので記号プログラミングに使用できる
  • &演算子を活用すればToStringメソッドを使わなくても文字列に変換できる
  • Booleanから数値型への暗黙の型変換を活用すると色々な数値を得ることが出来る。
  • CharAtメソッドを使わなくても文字列から一文字を切り出すことが出来る