상세 컨텐츠

본문 제목

[AHK] 사용 방법과 문법 - 2. Concepts and Conventions

IT이야기/AutoHotkey

by Rahs 2019. 8. 12. 06:00

본문

주의

본 문서는 AutoHotkey 1.1 버전을 대상으로 작성되었습니다.

Usage and Syntax

Concepts and Conventions

본 문서에서는 AHK에서 사용되는 일반적인 용어 및 개념들에 대해 코드보다 설명 위주로 서술합니다.

사전 지식이 없는 독자를 대상으로 서술된 문서라고 나와있지만 사실상 프로그래밍과 자료 구조에 대한 기초 지식이 없는 독자들에게는 이해하기 쉽지 않은 문서인 듯 싶으니 마음의 준비를 하시는 편이 좋겠...

Table of Contents

  • Values

    • Strings

    • Numbers

    • Boolean

    • Nothing

    • Objects

    • Object Protocol

  • Variables

    • Uninitialized Variables

    • Built-in Variables

    • Environment Variables

    • Caching

  • Functions/Commands

  • Control Flow

  • Details

    • String Encoding

    • Pure Numbers

    • Names

    • Variable References vs Values

    • References to Objects

Value

값이란 프로그램 내에서 사용되는 정보의 한 토막 또는 조각을 의미합니다.

예를 들자면 실행시켜야 할 프로그램의 이름이라던가, 단축키가 눌린 횟수, 활성화 시켜야 하는 창의

제목 등, 프로그램 또는 스크립트 내에서 의미를 가지는 모든 것을 '값'이라 할 수 있습니다.

AHK는 다음 3가지 형태의 '값'을 지원하고:

  • Strings (text)

  • Numbers (integers and floating-point numbers)

  • Objects

조금 다른 의미로 아래 2가지 개념을 사용합니다:

  • Boolean

  • Nothing


Strings

string은 단순히 '문자열'을 의미합니다. 문자열이란 1개 이상 문자가 나열된 형태의 값을 가리키며

그 전체를 하나의 개체로 취급합니다. 문자열의 길이(length)란 문자열을 이루고 있는 문자의 개수를

나타내며, 위치(position)란, 특정 문자가 문자열 내에서 몇 번째에 위치하고 있는지를 가리킵니다.

AHK에서 가장 첫 번째의 위치를 나타내는 수는 1입니다.

"사용 방법과 문법" 이라는 '길이' 9의 문자열에서 문자 "방"은 4번째에 '위치'합니다.

숫자로만 이루어진 문자열은 수학 연산(math operation) 또는 비교 연산(comparison)이 이루어지는

경우 AHK에 의해 자동으로 숫자 타입으로 간주되게 됩니다.

스크립트 내에서 어떻게 문자열이 사용되는지는 나중에 다시 살펴봅니다.

Numbers

AHK는 아래 3가지 숫자 형식(format)을 지원합니다:

  • 10진법 수 (e.g. 1323, 00123, -1)

  • 16진법 수 (e.g. 0x7B, 0x007B, -0x1)

  • 소수점을 가지는 10진법 수 (e.g. 3.14159)

16진수는 별도로 문서에 표시된 경우를 제외하면 반드시 0x 또는 0X의 접두어(prefix)를 가져야 하며

이 접두어는 + 또는 - 부호 뒤에, 그리고 자리수 표시를 위해 0표기가 필요한 경우, 이 0 표기 앞에

위치해야 합니다.

0x001   ; 바른 표기
-0X1 ; 바른 표기
000x1 ; 틀린 표기

소수점과 함께 사용된 숫자는 항상 10진수로 간주되고 이는 소수점 아래 자리 숫자가 0이라도

마찬가지 입니다. 42와 42.0은 대부분의 경우 상호 교환하여 사용이 가능하지만 항상 그렇지는 않기에

주의가 필요합니다.

소수점이 존재하는 경우에 한해 자연대수(e)도 인식합니다. (e.g. 1.0e4, -2.1eE4)

소수점은 항상 마침표(.)만 사용합니다.

콤마(,)를 소수점으로 사용하는 지역에서도 AHK에서는 소수점을 마침표로 사용해야 합니다.

Boolean

불 대수는 참 또는 거짓의 2가지 값 중 하나의 값만을 가질 수 있습니다.

단, AHK에서는 boolean 타입을 별도로 지원하는 것은 아니며 0과 1의 2가지 숫자로 이 상태를

갈음합니다. 0은 false, 1은 true를 나타내죠.

내장 변수 true와 false는 각각 1과 0의 값을 가지고 있어서 코딩 시에는 true 또는 false라는 표현을

사용해 가독성을 확보할 수 있도록 설계되어 있습니다.

Nothing

AHK는 타 언어에서 흔히 말하는 'null'에 대한 개념이 없습니다.

타 언어들에서는 null, nil, undefined 등의 표현이 있는데 말이죠.

말 그대로 아무것도 없는 상태를 나타내는 표현인데, AHK에서는 공백문자열 ""로 이를 갈음합니다.

Objects

객체라는 것은 2가지 관점에서 살펴볼 수 있겠습니다. 보는 관점에 따라 그 본질에 대한 설명이 달라질 뿐입니다만

그 설명이라는 것이 어떻게 달라지는지만 한번 살펴보죠.

  • 객체는 여러 값을 포함하는 '그룹' 자체를 하나의 '값'으로 취급할 수 있도록 정의된 자료 타입입니다. 즉, 객체라는 것은 어떤 item들의 나열이나 배열을 나타낼 수도 있고, 그런 나열이나 배열의 나열 또는 배열을 나타낼 수 있다는 거죠. 화면상 위치 좌표를 나타내는 X 및 Y 좌표값의 set과 같이 유관한 값들의 집합을 나타내는데 유용하게 사용됩니다. 여러 객체들을 조합해서 복잡한 자료 구조를 형성하는데 사용될 수도 있죠.

  • 객체란 어떤 '것' 또는 '행위', 또는 그 무언가를 나타내기 위한 것으로 스크립트에서 그 어떤 '것'이나 '행위'와 상호작용 할 수 있도록 해주는 그 무언가, 라고 볼 수도 있습니다. 예를 들어 BankAccount(은행 계좌)라는 이름의 객체에는 계좌 번호, 잔액, 계좌주명과 같은 속성(propertis)과 입금, 출금 같은 행위(methods)가 정의되어 있을 수 있겠습니다.

객체를 적절하게 사용한다면 (조금 더 명확하게 표현하자면, 클래스를 사용한다면), 보다 모듈화되고\

재사용성이 좋은 코드를 만들 수 있습니다. 모듈화가 잘 된 코드는 대개 이해하고 테스트하고, 또

유지보수 하기 쉽죠. 정말 굉장히 중요한 이야기입니다만 이건 설명서에서 열댓줄로 다룰 부분이

아니기 때문에 '객체지향'이라는 키워드만 기억해두고 객체에 대한 더 상세한 이야기는

사용 방법과 문법 12주제 Objects에서 다루도록 합니다.

Object Protocol

이 부분은 후에 나오는 변수함수에 대한 개념 이해가 선행되어야 이해가 가능합니다.

객체는 기본적으로 '메시지 전달'이라는 원칙 하에 동작합니다.

다시 말해 사용자는 객체 내의 코드나 변수가 어찌되어 있는지에 대해 알 필요없이, 객체에 입력으로

'메시지'를 전달하고, 객체가 돌려주는 응답을 돌려받는 식으로 객체를 '사용'하는 것이죠.

객체와 의사소통을 한다고 생각하면 거의 정확할 겁니다.

AHK에서 지원하는 객체와의 기본적인 의사소통 방식에는 3가지가 있습니다:

  • 값을 가져오는(Get) 것

  • := 를 이용해서 값을 지정하는(Set) 것

  • () 를 이용해서 method를 호출(Call)하는 것

여타 내용은 다시 내용이 중복되는 관계로 본 장의 12번째 section에서 다시 세세하게 다루도록 합니다.

Variables

AHK에서 변수는 사용과 동시에 생성됩니다. 초기화되지 않은 변수는 빈 문자열 값("")을 가지고

있어요. '변수'는 다음 3가지 요소로 구성된다고 볼 수 있습니다:

  • 변수의 '이름'

  • 변수 그 자체

  • 변수의 '값'

변수의 이름으로 사용할 수 없는 단어도 있는데 이 부분은 Names section을 참고하도록 합니다.

대체적으로 영문, 숫자와 밑줄(underscore, _)로 변수명을 구성하길 권장하며 숫자로 시작하는 이름은

사용하지 않는 것이 좋습니다.

변수의 이름은 scope(유효 범위)를 가집니다. 별도로 전역(global) 선언이 되지 않은 변수를

지역(local) 변수라고 부르며, 지역 변수는 해당 변수가 생성된 함수 안에서만 유효합니다.

변수는 값을 담는 그릇이라고 생각하면 대개 정확합니다. 변수와 변수의 값이 동일한 개념이 아니라는

것만 명확하게 이해한다면 이 부분에 있어 크게 주의를 기울일 부분은 없겠습니다.

Uninitialised Variables

초기값이 지정되지 않은 변수를 말합니다. AHK에서 초기값이 지정되지 않은 변수는 기본적으로

공백 문자열("")을 값으로 들고 있게 됩니다.

x라는 변수에 대해 초기화하지 않은 채 아래와 같이 사용하게 되면 원하는 결과가 나오지 않는다는

뜻입니다. 문자열과 숫자를 더할 수 없으니까요.

x := x + 1

실제로 아래 코드를 실행하면 빈 문자열이 결과 값으로 나올 겁니다.

x := x + 1
msgbox % x
return

초기화가 되지 않았기 때문이죠.

원하는대로 사용하려면 아래와 같이 초기화문 1줄만 덧붙여주도록 합니다.

x := 0
x := x + 1
msgbox % x
return

실행해보면 1이 출력되는 것을 볼 수 있습니다.

Built-in Variables

AHK에서는 자주 사용되는 제법 유용한 값들을 내장 변수의 형태로 제공하며, 이 내장 변수들은

scope와 관계없이 모든 스크립트에서 사용할 수 있습니다.

아래 몇 가지를 기억해두면 도움이 될 겁니다.

  • Clipboard와 ErrorLevel, command line parameters를 제외한 모든 내장변수는 '읽기 전용' 입니다.

  • Convention(규칙)에 의해 대부분의 내장 변수는 A_의 접두어를 붙이고 있습니다.

  • A_KeyDelay나 A_TitleMatchMode 같은 일부 내장 변수는 스크립트 동작을 제어하고 스레드별로 적용됩니다.

  • 일부 내장 변수는 호출될때마다 값이 변경되기도 합니다. A_TimeSinceThisHotkey라는 변수는 해당 핫키 스레드가 호출된 후로 경과한 시간을 ms단위로 가지고 있습니다.

내장 변수는 생각보다 굉장히 다양하고 유용하게 사용할 소지가 많습니다. 하나하나를 외울 필요는

없지만 필요할 때 검색해볼 수 있도록 존재만 확실하게 기억해두길 강력하게 권장합니다.

Environment Variables

환경 변수란 OS에 의해 통제되는 일련의 변수들을 일컫습니다. Windows 환경변수 보는 방법, 다들

아시죠..? 그 환경 변수를 필요에 따라 끌어와서 사용할 수 있는 겁니다.

스크립트에서는 환경 변수의 값을 변경하거나 새로운 환경 변수를 추가할 수도 있습니다.

새롭게 추가하거나 편집한 환경 변수를 시스템의 다른 프로그램들은 인지할 수 없지만, 스크립트

내에서 Run 또는 RunWait로 실행되는 프로그램들은 인지할 수 있습니다!

#NoEnv 지시자가 없다면, 환경 변수에 정의된 이름이 변수 명으로 사용되면 해당 환경 변수의 값으로 변수의 값을 초기화하게 됩니다. 혼란이 발생할 우려가 크기 때문에 #NoEnv 지시자 사용이 권장되며, 환경 변수 값이 필요할 경우, EnvGet 명령어를 사용하라고 권하고 있습니다.

Caching

프로그래밍의 세계에서 변수라는 것은 전통적으로 하나의 값을 보관하기 위해 도입된 개념이고,

그 값이라는 것은 명확하게 구분된 타입(string, number, object)을 가지기 마련이지만 AHK에서는

편의를 위해 변환이 가능한 경우에 한해 자동적인 타입 변환을 지원하고 있습니다.

아래와 같은 경우가 이 '자동 변환'에 해당됩니다.

string_number := "25"
actual_number := 5
converted_sum := string_number + actual_number
msgbox % converted_sum
return

string_number는 분명히 문자열 타입의 값 "25"를 가지고 있지만 actual_number 변수와의 '합' 연산을

위해 자동으로 숫자 타입으로 타입이 변환된 경우입니다. 그래서 (놀랍게도) 30이라는 결과 값이

대화상자로 표시되는데요, 더 재미있는 것은 이 뒤부터입니다.


AHK는 이제 string_number에 대해 2가지 값을 들고 있는 형태가 되는거죠. 자동 변환과 동시에

caching이 일어난 겁니다. 그런데 이 caching이 문제가 되는 경우도 있을 수 있습니다.

  • COM object를 사용하는 경우입니다. COM object에 변수를 전달해야 할 때, 숫자나 문자열 중 어느 한 가지 타입을 정해서 전달해야 하며, 타입 지정이 잘못되면 COM object가 예외를 발생시킬 수도 있습니다. 한 변수가 두 가지 타입의 값을 가지고 있는 경우, "숫자"를 사용합니다. 대부분의 경우 정상적인 결과가 반환되지만 그렇지 않은 경우는 caching에 의한 타입 문제가 아닌지를 의심해볼 필요가 있습니다.

  • 객체는 한 가지 값(key 또는 value)에 서로 다른 두 가지 타입의 값을 저장할 수 없습니다. 이 경우, 저장 시 메모리 사용효율이 좋은 '숫자'로 값을 저장하게 됩니다. (소수점을 가지는 유리수 표기 시 제외)

SetFormat 명령어의 slow mode를 사용하면 숫자를 변수 값으로 넣는 즉시 문자열 값으로 저장합니다.

정수를 입력했다면 숫자 값도 함께 저장되기 때문에 실 사용 시 처리 속도에는 차이가 발생하지

않습니다.

유리수의 경우에는 SetFormat 명령어에서 지정하기에 따라 소수점 아래가 잘리는 등 정확한 숫자 값이

달라지기 때문에 숫자 값은 저장하지 않습니다.

Functions/Commands

함수와 명령어들입니다.

AHK에서 본질적으로 함수와 명령어는 동일합니다. 다만 AutoHotkey v1이 사용된 기간이 굉장히

길었고 하위호환성의 중요성이 강조되다보니 예전 방식의 문법을 통해 사용되는 명령어와 표현 문법을

사용하는 함수대한 설명이 다소 혼란스러울 수도 있겠습니다.

가능한 혼란이 없도록 글을 옮겨보겠습니다.

함수, 또는 명령어를 사용하기 위해서는 일련의 매개변수를 '정해진 순서'대로 전달해야 합니다.

각각의 매개변수는 쉼표(,)로 구분되고, 경우에 따라 특정 매개변수들은 생략될 수 있습니다. 생략된

매개변수의 위치는 공란(blank)으로 남겨두게 됩니다. 나머지 매개변수도 모두 생략되는 경우,

이어지는 쉼표들도 모두 생략할 수 있습니다.


예로써 ControlSend 명령어를 살펴보죠.

ControlSend [, Control, Keys, WinTitle, WinText, ExcludeTitle, ExcludeText]

대괄호 자체는 실제 코드에 사용되지 않지만 안에 포함된 매개변수들에 대한 생략이 가능하다는 것을

나타냅니다. 다만 Keys 매개변수가 생략되는 경우 ControlSend 명령어 자체가 무용지물이 되는 작은

문제가 있겠네요.

실제로 사용되는 예를 조금 살펴보겠습니다.

ControlSend, Edit1, ^{Home}, A ; Control이 명시되었기 때문에 올바른 사용 예가 됩니다.
ControlSend, ^{Home}, A ; 잘못된 매개변수가 지정되어 올바르지 않은 사용입니다.
ControlSend,, ^{Home}, A ; Control 매개변수가 생략되었지만 올바른 사용 예가 됩니다.

제일 위의 명령어는 현재 활성화되어 있는 창(A)의 Edit1이라는 이름을 가지는 컨트롤에 컨트롤

(Ctrl)+Home키를 입력하는 동작을 수행합니다.

세번째 명령어는 현재 활성화되어 있는 창(A)에 Ctrl+Home 키를 입력하게 됩니다.

Methods

특정 객체에서만 동작하는 함수를 method라고 부릅니다. Send라는 함수는 한 개가 있지만

특정 객체 안에서 새롭게 정의된 Send 함수가 있다면 정의된 수만큼의 Send method가 존재한다고

볼 수 있다는 겁니다.

그냥 '객체 안에 정의된 함수'를 'method'라고 하는 구나! 정도만 기억하면 되겠습니다.

Control Flow, Details

Control flow는 프로그램의 흐름을 말합니다. 흔히 '로직(logic)'이라는 단어로 대체됩니다.

Details 섹션에 기억해둘만한 설명이 몇 가지 추가되어있는데 아래 내용들은 필요에 따라 참고하시면

되겠습니다. 각각이 무엇을 의미하는지까지 모두 알면 좋겠지만 본문을 이해하는데 반드시 요구되는

내용은 아니거든요 :)


  • AHK에서는 문자열 encoding charset으로 UTF-16을 사용합니다.

    • FileRead, FileAppend, FileOpen과 File object는 텍스트 파일 읽기/쓰기 시 encoding 지정 가능

    • DllCall 사용 시 ANSI/UTF-16간 인/디코딩에 AStr 및 WStr 매개변수 타입이 사용됨

  • 숫자에는 표현 가능한 범위에 제약이 있습니다. 일반적인 경우에는 제약에 크게 연연할 필요가 없으나

    매우 정확하거나 매우 큰 혹은 작은 (음의) 수 사용이 요구되는 경우에는 참고가 필요할 수 있습니다.

    • 64 bit signed integers (-2의 63승부터 2의 63승-1)

    • 64 bit binary floating-point numbers (15자리의 유효숫자까지 지원되나 문자열로 변환되는 경우 float format에 따라 정확도가 달라지며 기본 설정은 6자리로 반올림되어 계산됩니다. SetFormat slow 모드가 스크립트 내 어디든 존재한다면 이 숫자들은 모두 문자열로 계산되며 말인즉슨 정확도도 유효숫자 6자리로 제한된다는 의미입니다.)

  • 변수명

    • 대소문자를 구분하지 않습니다.

    • 최대 길이는 253자입니다.

    • _ # @ $와 숫자, 문자(non-ASCII 문자도 포함하여) 사용이 가능합니다.

  • 객체 참조

    • 아래와 같이 참조하고 참조를 추가로 생성하고, 생성된 참조 및 객체를 삭제할 수 있습니다.

    ref1 := Object()    ; 첫번째 객체 생성 후 첫번째 참조를 생성
    ref2 := ref1 ; 첫번째 객체에 대한 새로운 두번째 참조를 생성
    ref1 := "" ; 첫번째 참조 해제
    ref2 := "" ; 두번째 참조 해제, 더 이상 참조되지 않는 첫번째 객체 삭제



End of Document


관련글 더보기

댓글 영역