変数名に全角スペースは使えるのかという話

意外といろんな言語で日本語(というかUnicode全般)を変数名とかに使えるけど、全角スペースとか使えちゃうの?クールじゃね?配列の添え字に使ったらやばくね? という話をしていて、気になってぐぐったが見当たらなかったので試した。

#!/usr/bin/perl

use strict;
use warnings;

use utf8;

my $文字列 = 1;
my $  = 2;

print $文字列, "\n";
print $ , "\n";

$ perl 日本語.pl
Unrecognized character \x{3000}; marked by

チッつかえねえーな

package main

import "fmt"

func main() {
	var あああ = 1
	var   = 2
	fmt.Println(あああ)
	fmt.Println( )
}
$ go run utf8.go
# command-line-arguments
.\utf8.go:7: invalid identifier character U+3000
.\utf8.go:9: invalid identifier character U+3000

どっちも普通の変数名は使えるのに、スペースは使えないとのこと。いや安全でいいんだけど。

どういうことかと思って調べてみる。

The Go Programming Language Specification

In The Unicode Standard 6.3, Section 4.5 “General Category” defines a set of character categories. Go treats those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters, and those in category Nd as Unicode digits.

Goの場合はUnicodeのGeneral categoryというプロパティに従って文字として使えるかが決まっており、Lu, Ll, Lt, Lm, LoならUnicode characterとして使えると。へぇ。たぶんPerlも同じようなことになってるんだろう。

Unicodeの規格書? http://www.unicode.org/versions/Unicode7.0.0/ の4.5 General Category を読むと意味がわかる。文字ごとにgeneral categoryというのがあって、それぞれの文字の使い道が示してあるとのこと。

そこで全角スペース(U+3000)を調べると、

http://unicode.org/cldr/utility/character.jsp?a=3000

と出てきて、Space Separator (Zs)であることがわかる。SeparatorなのでGoでは(そしておそらくだいたいの言語でも)変数名に使えないようになっているんですね。へぇ。ちなみに、Separatorとされているからといって言語上の区切り文字として使えるというわけでもないらしい。不憫である。

ちなみにすべてのUnicodeのプロパティ一覧は扱いやすい感じのテキストで提供されている。便利そうだけど可能なら死ぬまで使いたくないですね?