Pular para o conteúdo principal

Expressões

Expressão é uma linguagem de expressões que consiste nas funções fornecidas pelo Excel com alguns acréscimos.

Assim como as funções, as expressões podem ser usadas diretamente nos cards.

Sintaxe das expressões​

As expressões podem ser referenciadas diretamente no código, mas precisam ser prefixadas com @ quando usadas dentro de strings. Quando usadas dentro de strings, também é possível definir um bloco de expressão @(), dentro do qual as expressões podem ser usadas sem o prefixo @.

Os nomes de funções e variáveis não diferenciam maiúsculas de minúsculas, portanto UPPER é equivalente a upper.

O exemplo a seguir mostra três maneiras diferentes de usar expressões para concatenar strings:

card First, then: Second do
a = "pizza"
b = "cheese"

# Referencia as expressões diretamente
result = concatenate(a, " with ", b)

# Envia "Tonight we have pizza with cheese"
text("Tonight we have @result")
end

card Second, then: Third do
a = "pizza"
b = "cheese"

# Referencia as expressões em um bloco @() dentro de uma string
# Envia "Tonight we have pizza with cheese"
text("Tonight we have @(concatenate(a, \" with \", b))")
end

card Third do
a = "pizza"
b = "cheese"

# Referencia as expressões dentro de uma string
# Envia "Tonight we have pizza with cheese"
text("Tonight we have @a with @b")
end

Expression v3​

O Expression v3 é a versão mais recente do motor de expressões. As jornadas estão sendo migradas gradualmente: as jornadas existentes continuam avaliando exatamente como antes, e as jornadas que usam o v3 indicam isso no painel de configurações da jornada e no editor de blocos de código.

O que muda no v3​

Nas versões anteriores, valores armazenados como texto — campos de contato são um exemplo comum — eram convertidos automaticamente em valores tipados antes de chegarem às suas expressões: "30" virava o número 30, "true" virava um booleano e um texto com formato de data virava uma data. Isso era conveniente, mas imprevisível: um código postal como "04102" podia virar um número silenciosamente e perder o zero à esquerda.

No v3, os valores mantêm seus tipos originais. Texto continua sendo texto, a menos que você o converta explicitamente.

A capitalização das chaves também é preservada: as versões anteriores convertiam todos os nomes de campos para minúsculas (um campo armazenado como FirstName virava firstname), enquanto o v3 os mantém exatamente como foram armazenados. Isso não muda a forma de referenciar valores — as buscas não diferenciam maiúsculas de minúsculas em ambos os casos, então @contact.firstname continua encontrando um campo armazenado como FirstName — mas, ao exibir ou percorrer um mapa inteiro, suas chaves aparecem com a capitalização original.

A maioria das jornadas não é afetada:

  • Comparações numéricas continuam funcionando com texto que contém um número — @(age > 21) é true quando age é "30", porque as comparações interpretam números quando necessário.
  • A renderização de valores em mensagens ("Hello @contact.name") não muda.

O ponto de atenção é qualquer lugar em que um valor seja usado como um tipo diferente de texto:

card Check when contact.opted_in == "true" do
# No v3, compare campos de texto com texto explicitamente.
# (No v2, "true" era convertido silenciosamente em booleano.)
text("You are opted in!")
end

Convertendo valores explicitamente​

O v3 adiciona funções de conversão para que você seja deliberado com os tipos:

card MyCard do
age = int(contact.age) # "30" -> 30
score = number(contact.score) # "4.5" -> 4.5
opted = boolean(contact.opted) # "true" -> true
code = text(contact.postcode) # qualquer coisa -> texto

text("Next year you will be @(age + 1)")
end

Se um valor não puder ser convertido, a função retorna um valor de erro que você pode verificar, em vez de produzir silenciosamente algo inesperado.

Respostas dinâmicas​

Aqui está um exemplo que usa uma expressão para responder com o nome do contato em forma capitalizada:

card Card do
text("Hello @PROPER(contact.name)")
end

Aqui está um exemplo de Quiz de Matemática que usa expressões para gerar números aleatórios e verificar a resposta.

card Calculator, "try again!", then: Answer do
calculator_number_1 = rand_between(1, 10)
calculator_number_2 = rand_between(1, 10)

ask("What is @calculator_number_1 * @calculator_number_2 ?")
end

card Answer when calculator == calculator_number_1 * calculator_number_2, then: Calculator do
buttons([Calculator]) do
text("That is correct!")
end
end

card Answer, then: Calculator do
buttons([Calculator]) do
text("""
@calculator is incorrect, the correct answer is:
@(calculator_number_1 * calculator_number_2)
""")
end
end

Botões dinâmicos​

Voltando ao nosso exemplo de mensagem com botões. Suponha que o conjunto de opções para os botões não seja conhecido antecipadamente; é possível gerar as opções dinamicamente usando expressões conforme este exemplo.

Você notará que o resultado final é o mesmo do exemplo anterior, mas estamos percorrendo uma lista chamada options, que tem o valor ["one", "two"].

O operador & neste exemplo indica uma função anônima e &1 é o primeiro argumento fornecido à função anônima. Consulte a referência para mais detalhes.

card Card do
options = ["one", "two"]

d =
buttons(Destination, map(options, &[&1, concatenate("Button ", proper(&1))])) do
text("click a button")
end
end

card Destination do
buttons([Card]) do
text("you clicked @d")
end
end

Referência​

Há uma longa lista de Expressões disponíveis. Você pode encontrar todas aqui

A seguir estão algumas das expressões mais usadas.

abs()​

Retorna o valor absoluto de um número.

card MyCard do
# Envia "The absolute value of -1 is 1"
text("The absolute value of -1 is @abs(-1)")
end

and()​

Retorna true se e somente se todos os seus argumentos forem avaliados como true.

concatenate()​

Une strings de texto em uma única string de texto.

card MyCard do
a = "Hi"
b = "and"
c = "welcome!"
text = concatenate(a, " ", b, " ", c)
# Envia "Hi and welcome!"
text("@text")
end

filter()​

Filtra uma lista, isto é, retorna apenas os elementos para os quais a expressão fornecida retorna um valor verdadeiro (truthy).

A expressão deve ser precedida pelo caractere &, e o item atual da lista sendo avaliado pela expressão está disponível com o placeholder &1:

card MyCard do
items = ["apple ", "bank ", "app ", "office ", "appointment "]
# Envia "apple app appointment"
text("@filter(items, &has_beginning(&1, \"app\"))")
end

find()​

Encontra o primeiro elemento da lista para o qual a expressão fornecida é verdadeira (truthy).

A expressão deve ser precedida pelo caractere &, e o item atual da lista sendo avaliado pela expressão está disponível com o placeholder &1:

card MyCard do
items = [["Hello", "World"], ["Hi", "World"]]
# O resultado é ["Hi", "World"]
result = find(items, & &1[0] == "Hi")
# Envia "Hi"
text("@result[0]")
end

first_word()​

Retorna a primeira palavra de uma string

card MyCard do
input = "One Two Three Four"
# Envia "One"
text("@first_word(input)")
end

fixed()​

Formata o número fornecido em formato decimal usando ponto e vírgulas.

card MyCard do
result = 4.209922
# Envia "The result is 4.21"
text("The result is @fixed(4.209922, 2)")
end

has_beginning()​

card MyCard do
text = "The Quick Brown Fox"
start = "the quick"
# Envia "true"
text("@has_beginning(text, start)")
end

isbool()​

Retorna true se o argumento for um booleano.

card MyCard do
a = "a"
# Envia "false"
text("@isbool(a)")
end

isnumber()​

Retorna true se o argumento for um número.

card MyCard do
a = 32
# Envia "true"
text("@isnumber(a)")
end

isstring()​

Retorna true se o argumento for uma string.

card MyCard do
a = "Hey!"
# Envia "true"
text("@isstring(a)")
end

left()​

Retorna os primeiros caracteres de uma string de texto. É seguro para Unicode.

card MyCard do
text = "The quick brown fox"
# Envia "The q"
text("@left(text, 5)")
end

lower()​

Converte uma string de texto para minúsculas.

card MyCard do
text = "HELLO!"
# Envia "hello!"
text("@lower(text)")
end

map()​

Retorna uma lista onde cada elemento é o resultado da invocação da expressão fornecida em cada elemento correspondente da lista fornecida.

A expressão deve ser precedida pelo caractere &, e o item atual da lista sendo avaliado pela expressão está disponível com o placeholder &1:

card MyCard do
items = ["a", "b", "c"]
# Envia "ABC"
text("@map(items, &upper(&1))")
end

reduce()​

Reduz elementos de uma lista aplicando uma função e coletando os resultados em um acumulador.

A expressão deve ser precedida pelo caractere &. O item atual da lista sendo avaliado pela expressão está disponível com o placeholder &1 e o acumulador está disponível com o placeholder &2:

card MyCard do
# Envia 6
text("@reduce(1..3, 0, & &1 + &2)")
end

reject()​

Rejeita itens de uma lista, isto é, retorna apenas os elementos para os quais a expressão fornecida retorna um valor falso.

A expressão deve ser precedida pelo caractere &, e o item atual da lista sendo avaliado pela expressão está disponível com o placeholder &1:

card MyCard do
items = ["apple ", "bank ", "app ", "office ", "appointment "]
# Envia "bank office"
text("@reject(items, &has_beginning(&1, \"app\"))")
end

uniq()​

Remove valores duplicados de uma lista.

card MyCard do
items = ["A", "B", "B", "C"]
# O resultado é ["A", "B", "C"]
result = uniq(items)
end

upper()​

Converte uma string de texto em MAIÚSCULAS.

card MyCard do
text = "hello!"
# Envia "HELLO!"
text("@upper(text)")
end

with_index()​

Envolve cada item da lista em uma nova lista com o item em si e seu índice na lista original.

card MyCard do
items = ["A", "B", "C"]
# O resultado é [["A", 0], ["B", 1], ["C", 1]]
result = with_index(items)
end