AutoHotkey の Object の書き方についてちゃんと調べたのでもう迷わないはず

AutoHotkey の Object を使っていて「なぜか値が入らない」「どのキーも同じ値を指している」といった現象に見舞われることが多かった。便利な概念なので使わないという選択肢は取りたくない。そこで気合を入れて挙動を調べることに。たぶんもう迷わない。

結論1

key1 という名前のキーに value1 という文字列を入れたい場合、以下のように書く。

; オブジェクトを新規作成する.
; このオブジェクト obj に対し、キー key1 に値 "value1" を入れたい.
obj := {}

; 方法1: ピリオドによる指定
obj.key1    := "value1"

; 方法2: [" "] 囲みによる指定
obj["key1"] := "value1"

; 以下の書き方は NG!!
;obj[key1] := "value1"

ここで一つハマりがちなのが obj[key1] := "value1" と書いてしまうこと。この書き方はダメ。この書き方だと 「key1という名前の変数に入っている値」をキー名として使う、という挙動になる。変数 key1 を定義していない場合、これは key[""] := "value1" と同義になってしまう(空文字列というキー名のキーに value1 という文字列を格納している)。

紛らわしいが、AutoHotkey には以下仕様があることに注意したい。

  • AutoHotkey の Object は「空文字列というキー名」も使える
  • AutoHotkey では未定義変数の中身は空文字列になる

結論2

keyname という変数に入っている値をキー名として用い、value1 という文字列を入れたい場合、以下のように書く。

obj := {}

keyname := "key1"

obj[keyname] := "value1"

変数 keyname がちゃんと定義されていることに注意すること。

スクリプト

調査として書いたスクリプト。

AutoHotkey v1.1.28 で動作確認済。

obj := {}

keyname     := "key4"

obj.key1    := "value1"
obj[key2]   := "value2"
obj["key3"] := "value3"
obj[keyname]:= "value4"
obj[""]     := "value-from-emptystring"

; 1 1 1 1
MsgBox % "key1=" obj.haskey(key1) ", key2=" obj.haskey(key2) ", key3=" obj.haskey(key3) ", key4=" obj.haskey(key4)

; 1 0 1 1
MsgBox % "key1=" obj.haskey("key1") ", key2=" obj.haskey("key2") ", key3=" obj.haskey("key3") ", key4=" obj.haskey("key4")

; value1 <Empty> value3 value4
MsgBox % "key1=" obj.key1 ", key2=" obj.key2 ", key3=" obj.key3 ", key4=" obj.key4

; value1 <Empty> value3 value4
MsgBox % "key1=" obj["key1"] ", key2=" obj["key2"] ", key3=" obj["key3"] ", key4=" obj["key4"]

; value-from-emptystring value-from-emptystring value-from-emptystring  value-from-emptystring
MsgBox % "key1=" obj[key1] ", key2=" obj[key2] ", key3=" obj[key3] ", key3=" obj[key4]

; 結論
;
; key1 というキーに value1 という文字列を入れたい場合.
;    obj.key1    := "value1"
;    obj["key1"] := "value1"
;
; key1 キーの値を参照したい場合.
;    obj.key1
;    obj["key1"]
;
; キー名を入れた変数 keyname を使ってアクセスしたい場合.
;    obj[keyname] := "value1"
;    MsgBox % obj[keyname]
; ※この時 keyname 変数が未定義だと「空文字列というキー」で登録されてしまう.