# Conceitos e Convenções

Este documento aborda alguns conceitos e convenções gerais usados pelo AutoHotkey, focando na explicação ao invés do código. Não se presume que o leitor não tenha nenhum conhecimento prévio de script ou programação, mas que deve estar preparado para aprender novas terminologias.

Para detalhes mais específicos sobre a sintaxe, veja Linguagem de Script.

## Tabela de Conteúdos

- Valores
  - Strings
  - Números
  - Boolean
  - Nada
  - Objetos
  - Protocolo de Objeto
- Variáveis
  - Variáveis não-iniciadas
  - Variáveis embutidas
  - Variáveis de Ambiente
  - Caching
- Comandos/Funções
- Controle de Fluxo
- Detalhes
  - Codificação de String
  - Números Puros
  - Nomes
  - Referências de Variáveis vs Valores
  - Referências para Objetos

## Valores

Um valor é simplesmente um pedaço de informação dentro de um programa. Por exemplo, o nome da tecla a ser enviada ou um programa para ser executado, o número de vezes que uma hotkey foi pressioanda, o título de uma janela a ser aberta ou qualquer coisa que possua algum significado dentro do programa ou script.

O AutoHotkey suporta esses tipos de valores:

- Strings (texto
- Números (Inteiros e decimais)
- Objetos

Alguns outros conceitos relacionados:

- Boolean
- Nada

### Strings

Uma string é apenas texto. Cada string é na verdade uma sequência ou uma cadeia de caracteres, mas pode ser tratada como uma única entidade. O comprimento de uma string é o número de caracteres na sequência, enquanto que a posição do caractere na string é simplesmente um número que aquele caractere representa numa sequência. Por convenção, o primeiro caractere está na posição 1 no AutoHotkey.

Strings numéricas: Uma string de dígitos (ou qualquer outro formato de número suportado) é automaticamente interpretada como um número quando uma operação matemática ou comparação a exige. No AutoHotkey v1, comparações são realizadas numericamente se ambos os valores forem numéricos e mesmo se ambos os valores forem strings. Entretanto, uma string cercada por aspas (ou o resultado de uma concatenaçaõ com uma string cercada por aspas) nunca é considerada numérica quando usada diretamente em uma expressão.

Como textos literais devem ser escritos no script depende do contexto. Para detalhes, veja Sintaxe Legado e Strings (em expressões).

Para uma explicação mais detalhada sobre como as strings funcionam, veja Codificação de String.

### Números

O AutoHotkey suporta esses formatos de números:

- Inteiros, como `123`, `00123` ou`-1`.
- Hexadecimais inteiros, como `0x7B`, `0x007B` ou `-0x1`.
- Números decimais, como `3.14159`.

Números hexadecimais precisam usar o prefixo `0x` or `0X` exceto onde foi anotado na documentação. Este prefixo precisa ser escrito após o sinal de `+` ou `-` se presente, e antes de qualquer sequência de zeros. Por exemplo, `0x001` é válido, mas `000x1` não é.

Números escritos com ponto decimal sempre são considerados como ponto de flutuação, mesmo se a parte fracional for zero. Por exemplo, `42` e `42.0` normalmente são substituíveis, mas nem sempre. Notação científica também é reconhecida, mas apenas se um ponto decimal estiver presente (por exemplo, `1.0e4` e `-2.1E-4`).

O separador decimais sempre é um ponto, mesmo se as configurações do usuário especificam ma vírgula.

Quando um número é convertido em uma string, ele é formatado de acordo com o formato inteiro ou decimal atual. Embora o comando SetFormat possa ser usado para alterar o formato atual, normalmente é melhor usar a função Format para formatar uma string. Números decimais também podem ser formatados usando a função Round.

Para mais detalhes sobre o alcance e a precisão dos valores numéricos, veja Números Puros.

### Boolean

Um valor boolean pode ser tantotrue oufalse. Valores Boolean são usados para representar qualquer coisa que possua exatamente dois estados, como a verdade de uma expressão. Por exemplo, a expressão `(x <= y)` é true quando x for menor ou igual a y.. Um valor boolean poderia também representar sim ou não, on ou off, baixo oucima (assim como o a função GetKeyState) e adiante.

O AutoHotkey não possui um tipo de boolean específico, então ele usa o valor inteiro `0` para representar false e `1` para representar true. Quando um valor precisa ou true ou false, um espaço em branco ou um valor zero é considerado false e todos os outros valores são considerados true. (Objetos sempre são considerados true.)

As palavras `true` ou `false` são variáveis embutidas contendo 1 e 0. Elas podem ser usadas para fazer um script mais legível.

### Nada

O AutoHotkey não possui um valor que representa unicamente nada, null, nil ou undefined, como visto em outras linguagens. Ao invés disso, uma string vazia (uma string com zero de comprimento) possui esse significado.

Se uma variável ou parâmetro é dito como "vazio" ou "blank", isso normalmente significa que é uma string vazia (uma string com zero de comprimento).

### Objetos

Geralmente há duas maneiras de visualizar objetos:

- Um objeto contém um grupo de valores, permitindo que o grupo por si próprio seja tratado como um valor. Por exemplo, um objeto poderia conter um array ou sequência de itens, ou um grupo de valroes relacionados como as coordenadas X e Y na tela. Objetos podem ser usados para construir estruturas complexas combinando-os com outros objetos.
- Um objeto pode representar uma coisa, um serviço, ou qualquer outra coisa, e pode oferecer maneiras para o script interagir com essa coisa ou serviço. Por exemplo, um objeto BankAccount pode ter propriedades como número da conta, saldo atual, o dono da conta e os métodos para retirar ou depositar uma quantidade.

O propósito do uso de objetos (e em particular, classes) pode resultar em um código que é modular e reusável. Código modulares normalmente são fáceis de testar, entender e preservar. Por exemplo, um pode melhorar ou modificar uma seção de código sem precisar saber os detalhes das outras seções, e sem precisar fazer mudanças correspondentes nessas seções. Códigos reusáveis econimizam tempo, evitando a necessidade de escrever e testar códigos para as mesmas repetidamente.

Quando você atribui um objeto para uma variável, como em `myObj := {}`, o qeu você armazena não é o objeto em si, mas uma referência para o objeto. Copiar aquela variável, como em `yourObj := myObj`, cria uma nova referência para o mesmo objeto. Uma alteração como `myObj.ans := 42` seria refletida por ambos `myObj.ans` e `yourObj.ans`, visto que ambos se referem ao mesmo objeto. Entretanto, `myObj := Object()` afeta apenas a variável myObj, não a variável yourObj, que continua fazendo referência para o objeto original.

### Protocolo de Objeto

Essa seção baseia-se nesses conceitos que serão abordados em seções posteriores: variável e funções

Objetos funcionam através do princípio da transmissão de mensagem. Você não sabe onde o código de um objeto ou variáveis residem na verdade, então você precisa transmitir uma mensagem para o objeto, como "me dê foo" ou "vá fazer uma barra", e confia no objeto para responder a mensagem. Os objetos no AutoHotkey suportam as seguintes mensagens básicas:

- Get um valor.
- Set um valor, indicado por `:=`.
- Call um método, indicado por `()`.

Cada mensagem pode opcionalmente ter um ou mais parâmetros (and, Set, o valor). Normalmente há pelo menos um parâmetro e ele é interpretado como o nome da propriedade ou método, uma key, um array index, dependendo do objeto e como você está usando ele. Os parâmetros de uma mensagem são especificados usando três padrões diferentes: `.Name`, `[Parameters]` e `(Parameters)`, onde Name é um nome ou identificador literal e Parmeters são uma lista de parâmetros (assim como sub-expressões), que podem ser deixadas vazias/em branco (`[]` or `()`).

Para Get e Set, `.Name` e `[Parameters]` parâmetros podem ser usados alternadamente, ou em combinação:

    myObj[arg1, arg2, ..., argN]
    myObj.name
    myObj.name[arg2, ..., argN]

Para Call, `.Name` e `[Parameter]` pode ser usado alternadamente e sempre precisa ser seguido por `(Parameters)`:

    myObj.name(arg2, ..., argN)
    myObj[arg1](arg2, ..., argN)

Perceba que se `name` estiver presente, ele se torna o primeiro parâmetro. `myObj.name` é equivalente à `myObj["name"]`, enquanto que `myObj.123` é equivalente à `myObj[123]`. Isso é verdadeiro para qualquer tipo de objeto, então sempre é possível computar o nome de uma propriedade ou método durante tempo de execução, ao invés de fazer um código longo e complicado no script.

Entretanto, name ou arg1 são considerados o primeiro parâmetro, lembre que eles são apenas mensagens e objetos são livres para lidar com eles em qualquer lugar. Em uma chamada de método como as mostradas acima, normalmente o objeto usa o nome ouarg1 para identificar qual método deve ser chamado, e então apenas o arg2 e o que estiver adiante são passados para o método. Na verdade, o arg2 torna-se o primeiro parâmetro aparente do méodo.

Geralmente, Set possui o mesmo significado de uma atribuição, então ele usa o mesmo operador.

    myObj[arg1, arg2, ..., argN] := value
    myObj.name := value
    myObj.name[arg2, ..., argN] := value

Atualmente existe também uma sintaxe "híbrida" que é permtida com Set, mas é melhor não usá-la.

    myObj.name(arg2, ..., argN) := value

Tecnicamente, o `valor` é passado para o último parâmetro da mensagem Set; embora que esse detalhe nem sempre é relevante para os autores de scripts. Geralmente, pode-se pensar nisso simplesmente como "O valor sendo atribuído".

## Variáveis

Uma variável permite que você use um nome como um placeholder para um valor. Tal valor pode ser alteado repetidamente durante o tempo de execução do seu script. Por exemplo, uma hotkey usa uma variável `press_count` para contar o número de vezes que é pressionada, e envia uma tecla diferente sempre que `press_count` é um múltiplo de 3 (em todo terceiro pressionamento). Mesmo uma variável que tem apenas um valor atribuído pode ser útil. Por exemplo, uma variável `WebBrowserTitle` pode ser usada para fazer seu código fácil de ser atualizado quando você alterar seu navegador da internet preferido, ou se o título ou a classe da janela altear devido a uma atualização de software.

No AutoHotkey, variáveis são criadas usando elas. Cada variável não é permanentemente restrita a um único tipo de dado, ela pode manter um valor de qualquer tipo: string, número ou objeto. Cada variável começa vazia; em outras palavras, cada nova variável criada contém uma string vazia até que ela seja atribuída com algum outro valor.

Uma variável possui três características principais.

- O nome da variável.
- A variável em si.
- O valor da variável.

Certas restrições são aplicadas aos nomes das variáveis - Veja a página Nomes para detalhes. Em poucas palavras, é mais seguro manter nomes constituídos de letras ASCII (que são nesse caso, insensitivas), dígitos e underscores e tentar evitar nomes que comecem com um dígito.

O nome de uma variável possui um campo de aplicação, que define onde aquele nome pode ser usado no código para se referir a uma variável em particular; em outras palavras, onde a variável é visível. Se uma variável não estiver visível dentro de um campo de aplicação determinado, o mesmo nome pode se referir a uma variável diferente. Ambas variáveis podem existir ao mesmo tempo, mas apenas uma está visível para cada parte do script. Variáveis Globais são visíveis no "campo de aplicação global" (isto é, fora das funções), mas geralmente devem ser declaradas com o propósito de serem visíveis dentro de uma função. Variáveis Locais são visíveis apenas dentro da função que a criou.

Uma variável pode ser considerada um contêiner ou um local de armazenamento para um valor, então você encontrará frequentemente a documentação se referindo a valores de variáveis como os conteúdos da variável. Para uma variável `x := 42`, podemos dizer que a variável x possui o número 42 como seu valor ou que o valor de x é 42.

É importante perceber que uma variável e seu valor não são a mesma coisa. Por exemplo, podemos dizer "`meuArray` é um array", mas o que realmente queremos dizer é que meuArray é uma variável contendo uma referência pra um array. Estamos tomando um atalho ao usar o nome da variável para se referir a seu valor, mas "meuArray" é na verdade apenas o nome da variável; o objeto array não sabe que ele tem um nome, e poderia ser referido por muitas variáveis diferentes (e por muitos nomes).

### Variáveis não-iniciadas

Inicializar uma variável é atribuir um valor inicial. Embora o programa inicialize todas as variável automaticamente (uma string vazia sendo o valor padrão), é uma boa prática para um script sempre inicializar suas variáveis antes de usar. Dessa forma, qualquer um que ler o script pode ver quais variáveis o script está usando e quais valores iniciais elas têm.

Isso normalmente é necessário para que o script inicialize qualquer variável que terá um número. Por exemplo, `x := x + 1` não funcionará se x nunca tiver um valor atribuído, visto que a string vazia é considerada não-numérica. O script deve atirbuir um valor de inicialização, como `x := 0`. Existem alguns casos onde valores vazios são assumidos por 0, mas é melhor não confiar nisso.

Autores de scripts podem usar a diretiva #Warn para ajudar a encontrar instâncias onde uma variável é usada sem ter sido inicializada pelo script.

### Variáveis embutidas

Um número de variáveis úteis são embutidas no programa e podem ser referenciadas por qualquer script. Com a exceção de Clipboard, ErrorLevel, e parâmetros da linha de comando, essas variáveis são apenas de leitura; isso é, seus conteúdos não podem ser alterados diretamente pelo script. Por convenção, a maioria dessas variáveis iniciam com o prefixo `A_`, então é melhor evitar usar esse prefixo para suas próprias variáveis.

Algumas variáveis como A_KeyDelay e A_TitleMatchMode representam configurações que controlam o comportamento do script e mantém valores separados para cada segmento. Isso permite que sub-rotinas iniciadas por novos segmentos (assim como hotkeys, menus, timers e afins) alterarem as configurações sem afetar outros segmentos.

Algumas variáveis especiais não são atualizadas periodicamente, ao invés disso, seus valores são recuperados ou calculados sempre que o script faz referência para tais variáveis. Por exemplo, Clipboard recupera o conteúdo atual da área de transferência como texto e A_TimeSinceThisHotkey calcula o número de milisegundos decorridos desde que a hotkey foi pressionada.

Relacionado: lista de variáveis embutidas.

### Variáveis de Ambiente

Variáveis de ambiente são mantidas pelo sistema operacional. Você pode ver uma lista delas através do prompt de comando digitando SET e pressionado Enter.

Um script pode criar uma nova variável de ambiente ou alterar os conteúdos de uma existente com o comando EnvSet. Tais adições e alterações não são vistas pelo restante do sistema. Entretanto, quaisquer programas ou scripts que o script inicia através de Run ou RunWait normalmente herdam uma cópia das variáveis de ambiente do script pai.

É recomendável que todos os novos scripts recuperem as variáveis de ambiente como Path através do EnvGet:

    EnvGet, OutputVar, Path  ; Para explicação, veja  #NoEnv.

Se um script não possuir a diretiva #NoEnv, ler uma variável vazia retornará o valor da variável de ambiente com aquele nome, se houver uma. Isso pode causar confusão, então é recomendável que todos os novos scripts usem #NoEnv.

### Caching

Embora uma variável seja pensada como se possuísse um único valor com tal valor possuindo um tipo distinto (string, número ou objeto), o AutoHotkey é capaz de converter automaticamente entre números e strings casos como `minhaString + 1` e `MsgBox %meuNumero%`. Conversões como essas podem ocorrer frequentemente. Sempre que uma variável é convertida, o resultado é armazenado em cachê na variável.

Na verdade, uma variável pode ter uma string e um número simultaneamente. Isso normalmente melhora a performance do script sem pontos negativos, mas se uma variável conter um número e uma string, ela é um número ou uma string? Tal ambiguidade causa comportamentos inesperados em pelo menos dois casos:

1. Objetos COM. Primeiro, para passar parâmetros para um objeto COM o programa deve converter o conteúdo da variável ou em um número ou uma string. Alguns objetos COM lançam uma exceção se o tipo de valor errado for passado. Se uma variável possui ambos, o número é usado. É comum que isso obtenha o resultado correto, mas nem sempre.
2. Objetos não possuem a capacidade de armazenar um número e uma string como chave ou valor. Tendo em vista que números são mais eficientes, se uma variável possuir ambos, o número será usado (exceto para valores decimais usados como chaves)

O modo lento de SetFormatforça a atribuição de um número puro para converter imediatamente tal número para uma string. Para inteiros, o número também é armazenado, então não existem efeitos adversos além da performance. Para decimais, o número não é armazenado, visto que SetFormat afeta a precisão do valor, mesmo ao separar todas as casas decimais. Em outras palavras, o modo lento de SetFormat evita que decimais puros sejam armazenados em variáveis.

Obter o endereço de uma variável converte efetivamente o valor da variável para uma string, desativando o cachê até que o endereço da variável mude (isso acontece quando sua capacidade é alterada). Isso é devido a compatibilidade e porque o script pode alterar o valor indiretamente através do seu endereço a qualquer momento, fazendo o cachê impreciso.

### Relacionado

- Variáveis: uso básico e exemplos.
- Capacidade de Variável e Memória: detalhes sobre limitações.

## Comandos/Funções

Uma função ou comando são as coisas básicas pela qual um script faz alguma coisa.

Em suma, funções e comandos são a mesma coisa, portanto os conceitos explicados aqui são aplicados para ambos. Entretanto, a longa história do AutoHotkey v1 e o ênfase na compatibilidade resultaram em uma divisão entre comandos, que requerem a sintaxe legado e funções que requerem a sintaxe de expressão.

Comandos e funções podem ter muitos propósitos diferentes. Algumas funções podem não fazer mais que realizar um simples cálculo, enquanto outras possuem efeitos visíveis imediatamente, como mover uma janela. Um dos pontos fortes do AutoHotkey é a facilidade qual os scripts podem automatizar outros programas e realizar outras tarefas comuns simplesmente chamando algumas funções. Veja a lista de comandos e funções para exemplos.

Através desta documentação, algumas palavras comuns são usadas de formas que podem não ser óbvias para alguém sem experiência prévia. Abaixo há várias palavras/frases que são usadas frequentemente em relação à funções e comandos:

Chamar uma função ou comando

  Chamar uma função ou comando faz com que o programa invoque, execute ou analise-o. Em outras palavras, uma chamada de função transfere temporariamente o controle do script para a função. Quando a função completar seu propósito, ela retorna o controle para o script. Em outras palavras, qualquer código que venha depois da chamada de função não é executado até que a função seja completada.

  Entretanto, às vezes uma função ou comando é concluída antes que seus efeitos possam ser vistos pelo usuário. Por exemplo, o comando Send envia pressionamentos de tecla, mas pode retornar antes que os pressionamentos de tecla alcancem seu destino e realizem seu efeito previsto.

Parâmetros

  Normalmente um comando ou função aceita parâmetros que dizem como operar ou no que operar. Cada parâmetro é um valor, como uma string ou número. Por exemplo, WinMove move uma janela, então seus parâmetros dizem qual janela mover e para onde movê-la. Parâmetros também podem ser chamados de argumentos. Abreviações comuns incluem param e arg.

Passando parâmetros

  Parâmetros são passados para uma função ou comando, o que quer dizer que um valor é especificado para cada parâmetro da função ou comando quando são chamados. Por exemplo, um pode passar o nome de uma chave para GetKeyState apra determinar qual tecla está sendo pressionada.

Retornar um valor

  Funções retornam um valor, portanto o resultado da função fica conhecido como um valor retornado. Por exemplo, StrLen retorna o número de caracteres em uma string. Comandos não retornam um resultado diretamente, ao invés disso eles armazenam o resultado em uma variável. Funções também podem fazer isso, por exemplo, quando existe mais do que um resultado.

Funções e comandos esperam que parâmetros sejam escritos em uma ordem específica, portanto o significado do valor de cada parâmetro depende da sua posição na lista de parâmetros delimitada por vírgulas. Alguns parâmetros podem ser omitidos, nesse caso o parâmetro pode ser deixado em branco. A vírgula seguinte só pode ser omitida se todos os parâmetros restantes também forem omitidos. Por exemplo, a sintaxe para ControlSend é:

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

Colchetes significam que os parâmetros envolvidos são opcionais (as chaves em si não devem aparecer no código atual). Entretanto, ControlSend não e útil a menos que as Chaves sejam especificadasm e normalmente uma também deve especificar a janela alvo. Por exemplo:

    ControlSend, Edit1, ^{Home}, A  ; Correto. Control foi especificado.
    ControlSend, ^{Home}, A         ; Incorreto: os parâmetros são incompatíveis.
    ControlSend,, ^{Home}, A        ; Correto. Control foi omitido.

### Métodos

Métodos são funções que operam em um objeto em particular. Embora possa haver apenas uma função chamada `Send` (por exemplo), pode haver quantos métodos chamados `Send` quanto objetos, cad objeto (ou classe de objeto) pode responder de uma forma diferente. Por esse motivo, o objeto alvo (que pode ser uma variável ou sub-expressão) é especificado do lado esquerdo do nome do método e não dentro da lista de parâmetros. Para detalhes, veja Protocolo de Objeto.

## Controle de Fluxo

Controle de fluxo é a ordem na qual declarações individuais são executadas. Normalmente as declarações são executadas sequencialmente a partir do topo para a base, mas uma declação de controle de fluxo pode sobrescrever isso, como especificar que as declarações devem ser executadas repetidamente, ou apenas se uma certa condição for atentida.

Declaração

  Uma declaração é o menor elemento autônomo da linguagem que expressa alguma ação a ser realizada. No AutoHotkey, declarações incluem comandos, atribuições, chamadas de funções e outras expressões. Entretanto, diretivas, labels (incluindo hotkeys e hotstrings) e declarações sem atribuições não são declarações; elas são processadas quando o programa é iniciado, antes do script executar.

Execute

  Realizar, colocar em efeito, pôr em prática, etc.... Executar basicamente significa a mesma coisa que fora da programação.

Corpo

  O corpo de uma declaração de controle de fluxo é a declaração ou grupo de declarações que são aplicadas. Por exemplo, o corpo de uma declaração if é executada apenas se uma condição especifica for atendida.

Por exemplo, considere o seguinte conjunto de instruções:

1. Abra o Bloco de Notas
2. Espere o Bloco de Notas aparecer na tela
3. Digite "Olá mundo!"

Nós damos um passo por vez, e quando o passo é finalizado, nos movemos para o próximo passo. Da mesma maneira, o controle em um programa ou script normalmente flui de uma declaração para a outra. Mas e se quisermos digitar dentro de uma janela existente do Bloco de Notas? Considere esse conjunto de instruções revisadas:

1. Se o Bloco de Notas não estiver em execução:
   1. Abra o Bloco de Notas
   2. Espere o Bloco de Notas aparecer na tela
2. Senão:
   1. Ative o Bloco de Notas
3. Digite "Olá mundo!"

Assim nós abriremos o Bloco de Notas dependendo se ele está ou não em execução. #1 é uma declaração condicional, também conhecida como declaração if; isto é, nós executamos seu corpo (#1.1 - #1.2) apenas se uma condição for atendida. #2 é uma declaração alternativa; executamos seu corpo (#2.1) apenas se a condição da declaração if anterior (#1) não for atendida. Dependendo da condição, o controle flui uma de duas maneiras: #1 (se a condição for verdadeira) → #1.1 → #1.2 → #3; ou #1 (se for falsa) → #2 (alternativa) → #2.1 → #3.

As instruções acima podem ser traduzidas no código abaixo:

    if (not WinExist("ahk_class Notepad"))
    {
        Run Notepad
        WinWait ahk_class Notepad
    }
    else
        WinActivate ahk_class Notepad
    Send Hello`, world!

Em nossas instruções escritas, usamos indentação para o grupo de declarações. Scripts funcionam de forma um pouco diferente. Embora a indentação faça o código fácil de se ler, no AutoHotkey ela não afeta o agrupamento de declarações. Ao invés disso, declarações são agrupadas através do envolvimento delas em chaves, como mostrado acima. Isso é chamado de bloco.

Para detalhes sobre a sintaxe - isto é, como escrever ou reconhecer declarações de controle de fluxo no AutoHotkey - veja Controle de Fluxo.

## Detalhes

### Codificação de String

Cada caractere em uma string é representado por um número, chamamos isso de número ordinal ou código do caractere. Por exemplo, o valor "Abc" seria representado da seguinte forma:

A | b | c
65 | 98 | 99 | 0

Codificação: A codificação da string define como os símbolos são mapeados para números ordinais e de números ordinais para bytes. Há muitas codificações diferentes, mas como todas aquelas suportadas pelo AutoHotkey incluindo ASCII como um subconjunto, os códigos de caracteres de 0 até 127 sempre possuem o mesmo significado. Por exemplo, 'A' sempre tem o código de caractere 65.

Terminação nula: Cada string é termianda com um "caractere nulo", em outras palavras, um caractere com valor binário igual a zero marca o fim da string. Não é necessário armazenar o comprimento da string já que ele pode ser inferido pela posição do terminador-nulo. Devido a performance, às vezes o AutoHotkey também armazena o comprimento, assim como quando uma string é armazenada em uma variável.

OBS: Devido a dependência da terminação-nula, o AutoHotkey v1 normalmente não suporta strings com caracteres nulos embutidos. Tais strings podem ser criadas com VarSetCapacity() e NumPut() ou DllCall(), mas podem produzir resultados inconsistentes.

Codificação nativa: Embora o AutoHotkey forneça formas de trabalhar com texto em várias codificações, os comandos e funções -- e até certo ponto, a linguagem em si -- assumem que os valores da string estejam em uma codificação em particular. Isso é chamado de codificação nativa. A codificação nativa depende da versão do AutoHotkey:

- As versões Unicode do AutoHotkey usa UTF-16. O menor elemento em uma string UTF-16 são dois bytes (16 bits) Os caracteres unicode na faixa de 0 até 65535 (U+FFFF) são representados por uma única unidade de código de 16-bit de mesmo valor, enquanto que caracteres na faixa de 65536 (U+10000) até 1114111 (U+10FFFF) são representados por um par substituto; isto é, exatas duas unidades de código de 16-bits entre 0xD800 e 0xDFFF. (Para explicações adicionais sobre pares substitutos e métodos para codificá-los ou decodificá-los, procure na internet).

- As versões ANSI do AutoHotkey usam a página de código ANSI padrão do sistema, que depende da localidade do sistema ou da configuração "linguagem para programas não-Unicode". O menor elemento em uma string ANSI é um byte. Entretanto, algumas páginas de código contém caracteres que são representados por sequências de múltiplos vytes (esses sempre são os caracteres não-ASCII).

Caractere:Geralmente, outras partes desta documentação usa o termo "caractere" para se referir à menor unidade de uma string, bytes para string ANSI e unidades de código de 16-bit para strings Unicode (UTF-16). Por motivos práticos, o comprimento de uma string e as posições dentro de uma string são determinados pela contagem dessas unidades de tamanho fixo, mesmo que elas não sejam caracteres Unicode completos.

FileRead, FileAppend, FileOpen() e File object fornecem formas de ler e escrever textos em arquivos com uma codificação específica.

As funções StrGet e StrPut podem ser usadas para converter strings entre a codificação nativa e alguma outra codificação especificada. Toda via, elas normalmente são úteis apenas na combinação com estruturas de dados e a função DllCall. Strings que são passadas diretamente para ou a partir da função DllCall() oiden ser convertidas para ANSI ou UTF-16 usando os tipos de parâmetro `AStr` ou `WStr`.

Técnicas para lidar com as diferenças entre as versões ANSI e Unicode do AutoHotkey podem ser encontradas em Unicode VS ANSI.

### Números Puros

Um número puro ou binário é um que fica armazenado na memória em um formato que a CPU do computador pode trabalhar diretamente, como por exemplo, realizar matemática. Na maioria dos casos, o AutoHotkey converte automaticamente entre strings numéricas e números puros conforme for necessário e raramente diferencia entre os dois tipos. O AutoHotkey, sobretudo, usa dois tipos de dados para números puros:

- Inteiros assinados 64-bit (int64).
- Números decimais binários 64-bit (o formato double ou binary64 do padrão internacional IEEE 754).

Em outras palavras, scirpts são afetados pelas seguintes limitações:

- Inteiros devem estar dentro do intervalo de -9223372036854775808 (-0x8000000000000000, ou -263) até 9223372036854775807 (0x7FFFFFFFFFFFFFFF, ou 263-1). Ainda que valores altos possam ser contidos em uma string, qualquer tentativa de converter a string para um número (por exemplo, usando-o em uma operação matemática) pode render resultados inconsistentes.

- Números deciamis normalmente suportam 15 dígitos de precisão. No entanto, converter um número decimal para uma string faz com que o número seja arredondado de acordo com o formato decimal atual, que por padrão são 6 casas decimais. Se o modo "lento" de SetFormat estiver presente em qualquer lugar do script, números sempre são convertidos para strings quando atribuídos para uma variável.

OBS: Há algumas frações decimais quais o formato decimal binário não pode representar precisamente, então o número é arredondado para o número representável mais próximo. Isso pode conduzir a erros inesperados. Por exemplo:

    SetFormat FloatFast, 0.17  ; Show "over-full" precision
    MsgBox % 0.1 + 0           ; 0.10000000000000001
    MsgBox % 0.1 + 0.2         ; 0.30000000000000004
    MsgBox % 0.3 + 0           ; 0.29999999999999999
    MsgBox % 0.1 + 0.2 = 0.3   ; 0 (not equal)

Uma estratégia para lidar com isso é evitar comparações diretas, ao invés, compare a diferença. Por exemplo:

    MsgBox % Abs((0.1 + 0.2) - (0.3)) < 0.0000000000000001

Outra estratégia é sempre converter para string (aplicando assim arrendondamentos) antes de comparar. Existem duas formas de fazer isso especificando a precisão, e ambas são mostradas abaixo:

    MsgBox % Round(0.1 + 0.2, 15) = Format("{:.15f}", 0.3)

### Nomes

O AutoHotkey usa o mesmo grupo de regras de nomeamento para várias coisas, incluindo variáveis, funções, grupos de janelas, GUIs, classes e métodos:

- Case sensitivity: Nenhuma para caracteres ASCII.. Por exemplo, `CurrentDate` é o mesmo que `currentdate`. Porém, caracteres non-ASCII maiúsculos como 'Ã' não são considerados iguais às suas formas minúsculas, indenpendentemente da localização atual do usuário. Isso ajuda o script a se comportar consistentemente em várias localizações.
- Comprimento máximo: 253 caracteres.
- Caracteres permitidos: Letras, números, caracteres non-ASCII e os seguintes símbolos: _ # @ $

Por causa do estilo das convenções, geralmente é melhor nomear suas variáveis usando apenas letras, números e o caractere underscore (por exemplo: CursorPosition, Total_Items e entry_is_valid). Esse estilo permite que pessoas familiarizadas com outras linguagens de computação entendam seus scripts mais facilmente.

Embora que o nome de uma variável possa consistir inteiramente de dígitos, isso geralmente é usado apenas por futuros parâmetros de linha de comando. Assim como nomes numéricos não podem ser usados em expressões porque eles seriam vistos como números ao invés de variáveis. É melhor evitar começar um nome com um dígito, visto que esses nomes são confusos e serão considerados inválidos no AutoHotkey v2.

Já que os seguintes caracteres podem ser reservados para outros propósitovs no AutoHotkey v2, é recomendável evitar o uso deles: # @ $

Nomes de propriedades em classes possuem as mesmas regras e restrições que os nomes das variáveis, exceto que os três caracteres listados acima (# @ $) não são permitidos. Embora eles possam ser usados em uma definição de método, chamar tal método exigiria o uso de colchetes. Por exemplo, , `myObject.@home()` não é válido, mas `myObject["@home"]()` é aceitável.

### Referências de Variáveis vs Valores

Variáveis possuem certos atributos que confundem a linha entre uma variável e seu valor, mas é importante fazer a distinção. Em particular, considere objetos e parâmetros ByRef.

Embora possamos dizer que a variável `meuArray` contém um array (que é um tipo de objeto), o que a variável contém não é o array em si, mas uma referência ou ponto para o array. Qualquer número de variáveis pode conter uma referência para o mesmo objeto. Isso pode ser útil para pensar em uma variável como apenas um nome neste caso. Por exemplo, dar um apelido para uma pessoa não faz com que um clone dessa pessoa venha a existir.

Por padrão, variáveis são passadas para funções definidas pelo usuário através do valor. Em outras palavras, o valor contido pela variável é copiado na variável que corresponde ao parâmetro da função. Parâmetros ByRef permitem que você passe uma variável através de referência, ou em outras palavras, faz um parâmetro da função um nome alternativo para sua variável, permitindo a função atribuir um novo valor para sua variável.

Por uma variável conter apenas uma referência para um objeto e não o objeto em si, quando você passa uma variável para um parâmetro non-ByRef, o que a função recebe é uma referência para o mesmo objeto. Isso permite que a função modifique o objeto, mas não permite que a função modifique a variável que o chamador da função usou, porque a função tem apenas a referência para o objeto e não a variável.

### Referências para Objetos

Scripts só interagem indiretamente com um objeto, através de uma referência para o objeto. Quando você cria um objeto, o objeto é criado em alguma localização que você não pode controlar, e você recebe uma referência. Passar essa referência para uma função ou armazená-la em uma variável ou outro objeto cria uma nova referência para o mesmo objeto. Você libera uma referência simplesmente usando uma atribuição para substituí-la por outro valor. Um objeto é deletado apenas quando todas as referências são liberadas; você não pode deletar um objeto explicitamente e não deve tentar.

    ref1 := Object()  ; Cria um objeto e armazena a primeira referência
    ref2 := ref1      ; Cria uma nova referência para o mesmo objeto
    ref1 := ""        ; Libera a primeira referência
    ref2 := ""        ; Libera a segunda referência; o objeto é deletado

Se isso for difícil de se compreender, tente pensar em um objeto como uma casa alugada. Quando você aluga uma casa, você recebe uma chave que você pode usar para acessar a casa. Você pode receber mais chaves e usá-las para acessar a mesma casa, mas quando você encerra o contrato de aluguel, você precisa devolver todas as chaves para o alugador. Normalmente, uma casa não seria deletada, mas talvez o alugador mande você remover qualquer lixo que você tenha deixado; assim como os valores que você armazena em um objeto são liberados quando o objeto é deletado.