JavaScriptの識別子に中黒が使えるようになった ― 2024年06月07日 10時21分
JavaScriptの識別子(変数名、関数名、プロパティ名など)の2文字目以降に中黒「・」(U+30FB KATAKANA MIDDLE DOT)が使えるようになりました。以下のコードはChrome 124では構文エラーになりますが、Chrome 125では問題なく実行できます。
const シン・ゴジラ = 2016;
JavaScriptの識別子
中黒が使えるようになったのは、JavaScript(ECMAScript)の仕様が変わったからではありません。変わったのはUnicodeの仕様のほうです。Unicode 15.1.0(2023年9月)においてOther_ID_Continue
プロパティ(を持つ文字の集まり)に中黒が追加されました。
そもそもJavaScriptの識別子に使える文字は、Unicodeを参照して定義されています。ECMAScript 2023(2023年6月)では以下のようになっています。
- 識別子の1文字目に使える文字
-
- Unicodeの
ID_Start
プロパティを持つ文字 $
(U+0024 DOLLAR SIGN)_
(U+005F LOW LINE)
- Unicodeの
- 識別子の2文字目以降に使える文字
-
- Unicodeの
ID_Continue
プロパティを持つ文字 $
(U+0024 DOLLAR SIGN)- ゼロ幅非接合子(U+200C ZERO WIDTH NON-JOINER)
- ゼロ幅接合子(U+200D ZERO WIDTH JOINER)
- Unicodeの
(いわゆるアンダースコア「_」はID_Continue
プロパティを持つため、2文字目以降にも使えます。)
Unicodeの仕様も毎年のように改定されますが、ECMAScript仕様ではUnicodeの「最新バージョン」が参照されています。
Unicodeの識別子
UnicodeのID_Start
、ID_Continue
プロパティは、各種の「識別子」に使える文字として推奨されるものを表しており、UAX #31 Unicode Identifiers and Syntaxで以下の文字を含むものとして定義されています。
ID_Start
プロパティ-
- 一般カテゴリが
Letter
である文字 - 一般カテゴリが
Letter_Number
である文字 Other_ID_Start
プロパティを持つ文字- ただし
Pattern_Syntax
プロパティまたはPattern_White_Space
プロパティを持つ文字を除く(具体的にはⸯ
(U+2E2F VERTICAL TILDE)が除かれる)
- 一般カテゴリが
ID_Continue
プロパティ-
ID_Start
プロパティを持つ文字- 一般カテゴリが
Nonspacing_Mark
である文字 - 一般カテゴリが
Spacing_Mark
である文字 - 一般カテゴリが
Decimal_Number
である文字 - 一般カテゴリが
Connector_Punctuation
である文字 Other_ID_Continue
プロパティを持つ文字- ただし
Pattern_Syntax
プロパティまたはPattern_White_Space
プロパティを持つ文字を除く
ここでOther_ID_Start
プロパティとOther_ID_Continue
プロパティというのは、後方互換性のためにそれぞれID_Start
プロパティとID_Continue
プロパティに含めるべき文字を表しています。Other_ID_Continue
プロパティに中黒(U+30FB)が追加されたことで、巡り巡ってJavaScriptの識別子に中黒が使えるようになったのです。
なお、中黒だけでなくゼロ幅非接合子(U+200C)とゼロ幅接合子(U+200D)も追加されたため、ECMAScript 2024以降では識別子の2文字目以降に使える文字の定義が「UnicodeのID_Continue
プロパティを持つ文字または$
(U+0024 DOLLAR SIGN)」と簡潔になる予定です。
過去にも識別子に中黒が使えた
ID_Continue
プロパティの後方互換性のために中黒が追加されたということは、さらに以前は中黒がID_Continue
プロパティに含まれていたのでしょうか?
まさにその通りで、Unicode 4.0.1(2004年5月)以前は中黒の一般カテゴリがConnector_Punctuation
になっており、結果としてID_Continue
プロパティに含まれていました。Unicode 4.1.0(2005年3月)で中黒の一般カテゴリがOther_Punctuation
に変更され、ID_Continue
プロパティに含まれなくなっていたのです。
ECMAScript 5.1ではUnicode 3.0以上への適合が求められていたため、ECMAScript 3(1999年12月)~5.1(2011年6月)の間は中黒を識別子に使えた可能性があります。(ECMAScript 2(1998年8月)以前はASCIIの範囲内の文字のみ識別子に使用可能、ECMAScript 2015(ES6、2015年6月)以降はUnicode 5.1.0以上への適合が求められる。)
他のプログラミング言語の識別子
識別子の定義にUAX #31を参照しているのはJavaScriptだけではありません。C、C++、Perl、Python、Rustなど多くのプログラミング言語がUAX #31を参照しています。これらの言語でもそのうち識別子に中黒が使えるようになるでしょう(\p{Word}
との共通部分を採用しているPerlを除く)。
なお、JavaScript以外ではID_Start
、ID_Continue
プロパティではなく、XID_Start
、XID_Continue
プロパティを参照していることが多いです。これらのプロパティは、ある識別子にUnicode正規化を適用しても識別子として有効であり続けることを保証するため、それぞれID_Start
、ID_Continue
プロパティからいくつかの文字を除外しています。
参考文献
- UAX31: Unicode Identifier の話 | ++C++; // 未確認飛行 C ブログ
- UTC #176 properties feedback & recommendations (PDF)——「2.2 Katakana middle dots in XID_Continue」において、中黒が識別子に使えなくなったのは「うっかり(accidentaly)」だったと述べられている。
- PropList-4.0.1.txt——中黒(U+30FB)の一般カテゴリが
Connector_Punctuation
(Pc
)であることを確認 - PropList-4.1.0.txt——中黒(U+30FB)の一般カテゴリが
Other_Punctuation
(Po
)であることを確認 - PropList-15.0.0.txt——
Other_ID_Continue
プロパティに中黒(U+30FB)が含まれないことを確認 - PropList-15.1.0.txt——
Other_ID_Continue
プロパティに中黒(U+30FB)が含まれることを確認
Windowsでプロキシ自動設定ファイルを適用するPowerShellスクリプト ― 2020年03月21日 22時23分
Windowsで一時的にプロキシ自動設定ファイル(プロキシ自動構成スクリプト、pacファイル)を利用したいとき、
- プロキシ自動設定ファイルを配信するHTTPサーバーを立てなければいけない。(以前はローカルファイルが使えたが、Windows 10 Creators Updateから使えなくなった。)
- Windowsの「プロキシ」設定画面で「スクリプトのアドレス」を指定しなければいけない。
という手間があります。
そこで、プロキシ自動設定ファイルを配信するHTTPサーバーを立ち上げ、そのURLをWindowsのプロキシ設定に指定するPowerShellスクリプトを書きました。
上記リンク先のスクリプトをローカルに保存し、Explorerでスクリプトファイルのコンテキストメニューから「PowerShell で実行」を選択すると、コンソールウィンドウが開き、スクリプト中に記述されたプロキシ自動設定が適用された状態になります。コンソールウィンドウ内でCtrl + Cを押下すれば、プロキシ自動設定が解除されます。
なお、プロキシ自動設定でSOCKSプロキシを使う場合、そのためのSSH接続は別途立ち上げておく必要があります。
既知の不具合
EdgeやInternet Explorerではプロキシ自動設定が期待通り適用されないことがあるようです。
プロキシ設定の変更をブラウザに通知する
プロキシ設定はレジストリに保存されていますが、レジストリの値を書き換えるだけではうまく機能しませんでした。どうもプロキシ設定が変更されたことをWebブラウザなどの各アプリケーションに伝えるために、Windows APIを呼び出す必要があるようです(スクリプト中のRefresh-Proxy-Settings
関数の処理)。
もっと言うと、プロキシ設定の変更自体もレジストリを直接いじるのではなく、WinInetライブラリのInternetSetOption
関数経由でやったほうがよいようです。ただし、そのためには構造体を定義するなど、PowerShellスクリプト中にC#のコードを書く必要があり、面倒になってやっていません。
Windows PowerShellの感想
今回初めてWindows PowerShellを書いたのですが、.NET Frameworkをそのまま使え、C#のコードを書け、Windows APIまで呼び出せるなど、何でもできる感じで感心しました。Task
オブジェクトを直接扱うことでC#のasync
/await
相当の処理を実現できるのも面白かったです。
もっとも、気をつけないと「PowerShellを書いていたつもりが、いつの間にかC#を書いていた」ということになりかねませんが(笑)
xargsで入力が空のときに何も実行しない ― 2019年12月31日 19時56分
xargs
コマンドで入力が空のときは何も実行しないようにしたいのですが、BSD版(macOSなど)とGNU版(Linuxなど)などで挙動が異なります。BSD版は最初からそのような挙動なのに対し、GNU版では--no-run-if-empty
オプションをつけないとそのような挙動になりません。両者で挙動を合わせるために、シェルスクリプトで以下のように書けます。
NO_RUN_IF_EMPTY=$(: | xargs echo '--no-run-if-empty')
command1 | xargs $NO_RUN_IF_EMPTY command2
コロン(:
)は何もしないコマンドであり、パイプでつながれたxargs
の入力も空となります。なので、BSD版ではecho
コマンドが実行されずNO_RUN_IF_EMPTY
変数の値が空文字列となり、一方GNU版ではecho
コマンドが実行されNO_RUN_IF_EMPTY
変数の値に文字列'--no-run-if-empty'
が入ります。
Windows 10 で Emacs キーバインディングを利用するための設定のメモ ― 2016年01月31日 11時26分
Windows の操作全般および MS-IME で Emacs のようなキーバインディングを利用するための個人的なメモ。
Ctrl キーの位置調整
Change Key を利用。管理者として実行する。
- CapsLock → Ctrl (左)
- カタカナ/ひらがな → Shift (右)
- 半角/全角 → Esc
XKeymacs の設定
XKeymacs のスナップショットバージョンを利用。Explorer を「管理者として実行」し、その上で C:\Program Files
にフォルダをコピー。
dot.xkeymacs
以下の内容でファイル %APPDATA%\dot.xkeymacs
(たいていは C:\Users\{user}\AppData\Roaming\dot.xkeymacs
) を作成。
(fset 'browser-back [browser-back])
(fset 'browser-forward [browser-forward])
(fset 'find-next [f3])
(fset 'find-previous [?\S-f3])
プロパティ全般
- 「ダイアログにはダイアログ専用の設定を利用する」を無効化
- 個人的には設定を共通化したほうが楽。
- 「Microsoft IME (IME)」に対しては「XKeymacs を無効にする」を選択
- MS-IME には後述の設定を適用するので、XKeymacs 側で何かする必要はない。
(2021-04-25 追記)
プロパティの「基本」タブ
- 「アクティブウィンドウから離れる」の C-z 及び M-F12 を無効化
- C-z は素通しさせ、「元に戻す」として扱う。
- 「消去、編集」の C-t 及び C-x C-t を無効化
- C-t は screen でのメタキーとしてのみ用い、他の用途には使わない。
- 「その他」の Esc 及び C-[ を無効化
- メタキーには Alt のみ用い、Esc は Esc としてのみ用いる。
- 「IME の切替え」の全項目を無効化
- IME のオン / オフは変換 / 無変換キーで行う。
- 「その他」の C-x h を無効化
- 「移動」の C-l、「消去、編集」の C-k、「その他」の C-u を無効化
- MS-IME に対して「XKeymacs を無効にする」としていても、Firefox など (IME で入力中の文字列を自前で描画するアプリケーション?) では MS-IME での入力中に XKeymacs の設定が適用されてしまうので、MS-IME のキー設定と干渉するものは無効化しておく。
- 「その他」の C-0 ... C-9 を無効化
- 誤爆しかしない。必要なコマンドの数を事前に算出し、正しい数値のキーを打つのは私には困難。
プロパティの「詳細」タブ
- 「その他」の Esc に Ctrl + [ を割り当て
- C-[ は Meta ではなく単なる Esc として用いる。
- 「その他」の Temporarily Disable XKeymacs に Ctrl + ; を割り当て
- C-; C-○ と打つことでネイティブのショートカットキーを利用できる。";" (セミコロン) はホームポジションなので打つのも簡単。
- 「その他」の Select All に Ctrl + X H を割り当て
- Firefox Nightly で C-x h が期待通り動作しないので、これをネイティブの「すべて選択」に置換する
- 「その他」の newline に Ctrl + J を割り当て
- 「オリジナルコマンド」の browser-back に Meta + , を、browser-forward に Meta + . を、find-next に Ctrl + . を、find-previous に Ctrl + , をそれぞれ割り当て
- "," (カンマ) は "<" (小なり) すなわち「←」(戻る方向) を、"." (ピリオド) は ">" (大なり) すなわち「→」(進む方向) を、それぞれ表す。
オプション
- 「XKeymacs」の「ログオン時に実行」を有効化
- 「コマンド プロンプト」の「ファイル名自動補完」を無効化
- 個人的には使わない。
(2021-04-25 追記)
MS-IME の設定
- 「スペースの入力」を「常に半角」
- 「Shift キー単独で英数モードに切り替える」を有効化
英数字及び記号類を「常に半角に変換」、ただし「~」のみ「変換しない」- 「英字」「数字」のみ「常に半角に変換」とし、「記号」は「前回の変換結果に従う」のまま (2021-04-25 追記)
MS-IME のキー設定
インポート / エクスポート機能がなさそうなので、ひとつずつ設定しなおしている。
キー | 入力/変換済み文字なし | 入力文字のみ | 変換済み | 候補一覧表示中 | 文節長変更中 | 変換済み文節内入力文字 | 備考 |
---|---|---|---|---|---|---|---|
無変換 | IME-オフ | 全消去 | 文節戻し | 候補閉 | 文節戻し | 全戻し | 何もなければ IME オフ、ほかは Esc と同じ |
Shift + 無変換 | かな切替 | かな切替 | かな切替 | かな切替 | かな切替 | かな切替 | |
変換 | IME-オン | 何もなければ IME オン、ほかは変更なし | |||||
Ctrl + 変換 | 再変換 | 何もなければ再変換、ほかは変更なし | |||||
Ctrl + A | 文字先頭 | 文節先頭 | 候補先頭 | - | 文字先頭 | Home と大体同じ | |
Ctrl + B | 文字左 | 文節左or文字左 | 文節左or文字左 | 文節左 | 文字左 | 「←」と同じ | |
Ctrl + C | - | - | - | - | - | 握りつぶす | |
Ctrl + D | 1文字削除 | 1文字削除 | 候補閉 | - | 1文字削除 | Delete と同じ | |
Ctrl + E | 文字末尾 | 文節末尾 | 候補最後 | - | 文字末尾 | End と大体同じ | |
Ctrl + F | 文字右 | 文節右 | 文節右 | 文節右 | 文字右 | 「→」と同じ | |
Ctrl + G | 全消去 | 文節戻し | 候補閉 | 文節戻し | 全戻し | Esc と同じ | |
Ctrl + I | 予測候補表示 | - | 候補表示切替 | - | - | Tab と同じ | |
Ctrl + J | 全確定 | 全確定 | 候補選択+確定 | 全確定 | 全確定 | Enter と同じ | |
Ctrl + N | 全変換 | 変換+次 | 変換+次 | 文節変換 | 全変換 | ||
Ctrl + P | 全変換 | 前候補 | 前候補 | 文節変換 | 全変換 | ||
Ctrl + Q | - | - | - | - | - | 握りつぶす | |
Ctrl + R | - | - | - | - | - | 握りつぶす | |
Ctrl + S | - | - | - | - | - | 握りつぶす | |
Ctrl + U | カタカナ | カタカナ | カタカナ | カタカナ | カタカナ | ||
Ctrl + V | - | - | - | - | - | 握りつぶす | |
Ctrl + W | - | - | - | - | - | 握りつぶす | |
Ctrl + X | - | - | - | - | - | 握りつぶす | |
Ctrl + [ | 全消去 | 文節戻し | 候補閉 | 文節戻し | 全戻し | Esc と同じ (2021-04-25 追記) |
Ctrl + H/K/L/M/O/T/Y/Z は変更なし。
MS-IME のキー設定の「機能選択」には「-」という項目がふたつ存在するが、先頭のものは MS-IME を利用しているアプリケーション側にそのキーを伝え、末尾のものは MS-IME 内でそのキーを握りつぶす。
あるキーに対する項目を選択した状態で「キー追加」を実行すると、元の項目をコピーして新たな項目を追加できる。(2021-04-25 追記)
XKeymacs を起動していると「割り当てるキー」を入力できないことがあるので、XKeymacs を終了した状態で設定する。(2021-04-25 追記)
はてなでコードを書くときに気をつけていること ― 2011年12月18日 14時37分
こんにちは、はてなでアプリケーションエンジニアをしている nanto_vi です。この記事は Hatena::Staff Advent Calendar 2011 の一環として書いています。Advent Calendar の会場ははてなブログとなっていますが、主催の antipop さんに尋ねたところ何でもよいというような返答があったのでここで書きます。
はじめに謝っておきますが、この記事ははてなとほとんど関係がありません。タイトルに「はてな」と入っているのは Advent Calendar の要件を満たすための目くらましあり、内容はといえばはてなのノウハウでもなんでもない、私が最近個人的に心がけていることです。ごめんなさい。
できれば明示的に
業務で書くコードは複数人により読み書きされメンテナンスされるので、わかりやすさが重要になってきます。わかりやすさを保つためには暗黙的に行われる操作を減らし、明示的にコードに表した方がよいと感じます。たとえば、Perl では、
use Encode;
# encode_utf8 関数は Encode モジュールで定義されている
my $octets = encode_utf8 $string;
のようにモジュール読み込み時に自動的に関数をインポートすることができますが、それよりも、
use Encode qw/encode_utf8/;
my $octets = encode_utf8 $string;
のようにインポートする関数を明示的に指定したほうが、その関数がどこで定義されているのかわかりやすいでしょう。
個人的には、関数や変数の名前で grep
をかけてその定義(外部で定義されている場合は宣言)を探し出せることが、「明示的」であるための最低線ではないかと思います。
入力には正規化を、出力には符号化を
アプリケーションを作るうえで入出力の扱いは避けて通れません。入力元はユーザーだったりバッチ処理スクリプトの引数だったり、出力先はユーザーだったりデータベースサーバーだったりしますが、いずれにおいても入力には正規化処理を、出力には符号化処理を、それぞれ施すことになります。
正規化は一般に不可逆です。空白文字類をすべてスペースに置換した後はもともとスペース以外の空白文字が含まれていたのかわかりませんし、数値「42」を生み出した入力は "42"
でも "42.0"
でも、はたまた "0x2A"
でもありえます。
符号化は一般に可逆です。あるデータをユーザーのもとへ送り届けるのに、そのデータを HTML のテキストとして扱えるよう一部文字を文字参照の形に符号化し、その HTML ソース全体を文字符号化方式 UTF-8 をもって符号化し、さらには HTTP メッセージに、TCP のセッションに、IP のパケットにと符号化を重ねていきますが、それらすべては符号化規則を逆に適用することで元の形式へ復元できます。
たとえば HTML として解析され、その結果が JavaScript の文字列として、HTML として、URI としてと順に解析されるデータを Template-Toolkit で出力する場合、解析の逆順でそれぞの形式に応じた符号化を施す必要があります。
<script type="text/javascript">
document.write('<a href="/search?q=[% word | uri | html | js %]">検索<\/a>');
</script>
script 要素の内容は CDATA 型であり文字参照は解決されないので、最後に html
フィルタをかけることはしません。また、そもそもこのような多重にフィルタをかける事態は避けたほうが賢明でしょう。
入出力いずれにおいても、データがどういう形式で扱われるのかを意識し、それに応じた正規化処理または符号化処理を施すことで、意図しない入力が致命的な挙動を引き起こすこともある程度は防げるのではないかと考えます。
最近のコメント