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