10. Biblioteca padrão
Métodos de listas e strings, e as funções globais disponíveis em qualquer lugar do script.
10.1 Métodos de lista
Seção intitulada “10.1 Métodos de lista”Percorrendo
Seção intitulada “Percorrendo”lista.each { |item| ... }
Seção intitulada “lista.each { |item| ... }”Executa o bloco para cada item.
check "each" { doc.pages.each { |page| assert page.width > 0, "página #{page.number} sem largura" }}lista.each_with_index { |item, i| ... }
Seção intitulada “lista.each_with_index { |item, i| ... }”Como each, mas o segundo parâmetro recebe a posição (começando em 0).
check "each_with_index" { doc.fonts.each_with_index { |font, i| print("fonte", i + 1, "de", doc.fonts.length, ":", font.name) }}Testando
Seção intitulada “Testando”lista.all { |item| ... }
Seção intitulada “lista.all { |item| ... }”Verdadeiro se todos os itens satisfazem a condição. Lista vazia devolve verdadeiro.
check "all" { require doc.fonts.all { |f| f.is_embedded } require doc.pages.all { |p| p.has_trim_box }}lista.any { |item| ... }
Seção intitulada “lista.any { |item| ... }”Verdadeiro se algum item satisfaz. Lista vazia devolve falso.
check "any" { assert doc.pages.any { |p| p.extract_text() != "" }, "documento inteiro sem texto"}lista.contains(valor)
Seção intitulada “lista.contains(valor)”Verdadeiro se o valor está na lista.
check "contains" { require [1, 2, 3].contains(2) require prepress::detect_spot_colors().contains("Verniz")}Transformando
Seção intitulada “Transformando”lista.filter { |item| ... }
Seção intitulada “lista.filter { |item| ... }”Nova lista só com os itens que satisfazem a condição.
check "filter" { ruins = doc.images.filter { |img| img.dpi < 300 } assert ruins.length == 0, "#{ruins.length} imagem(ns) com resolução baixa"
// Encadeando: filtrar e depois transformar nomes = doc.fonts.filter { |f| !f.is_embedded }.map { |f| f.name } print("fontes soltas:", nomes.join(", "))}lista.map { |item| ... }
Seção intitulada “lista.map { |item| ... }”Nova lista com o resultado do bloco para cada item.
check "map" { numeros = doc.pages.map { |p| p.number } larguras = doc.pages.map { |p| p.width } print("páginas:", numeros.join(", "))}Acessando
Seção intitulada “Acessando”lista.length
Seção intitulada “lista.length”Quantidade de itens. Funciona como propriedade ou método: lista.length e
lista.length() são equivalentes.
check "length" { require doc.pages.length == doc.page_count print("fontes:", doc.fonts.length)}lista.get(n)
Seção intitulada “lista.get(n)”O n-ésimo item, 1-based. Erro amigável se o índice não existe.
check "get" { linha = data::load_dataset("dados/lotes.csv").get(2) // segunda linha print("primeira coluna:", linha.get(1))}lista.first() e lista.last()
Seção intitulada “lista.first() e lista.last()”Primeiro e último item. Devolvem null em lista vazia (sem erro).
check "first e last" { primeira = doc.pages.first() ultima = doc.pages.last() print("da página", primeira.number, "até a", ultima.number)
// Seguro em lista vazia: null é falso spots = prepress::detect_spot_colors() assert !spots.first() || spots.first() == "Verniz", "tinta especial inesperada: #{spots.first()}"}lista.join([separador])
Seção intitulada “lista.join([separador])”Junta os itens em texto. Separador padrão: ", ".
check "join" { print(doc.fonts.map { |f| f.name }.join(", ")) print(prepress::get_page_boxes(1).join(" | ")) print([1, 2, 3].join(" -> "))}10.2 Métodos de string
Seção intitulada “10.2 Métodos de string”| Método | O que faz |
|---|---|
texto.contains(sub) |
Contém o trecho? |
texto.starts_with(sub) |
Começa com? |
texto.ends_with(sub) |
Termina com? |
texto.trim() |
Remove espaços das pontas |
texto.to_uppercase() |
Tudo em maiúsculas |
texto.to_lowercase() |
Tudo em minúsculas |
texto.length |
Quantidade de caracteres |
check "Métodos de string" { titulo = doc.title
require titulo.length > 0 require titulo.trim() == titulo // sem espaços sobrando assert !titulo.to_lowercase().contains("rascunho"), "título ainda marcado como rascunho"
codigo = codes::decode_barcode(1) assert codigo.starts_with("789"), "GTIN não brasileiro"
arquivo = doc.filename assert arquivo.ends_with(".pdf"), "extensão inesperada"}Diferença entre contains de string e de lista:
check "contains em cada tipo" { // string: procura um TRECHO dentro do texto require "documento final".contains("final")
// lista: procura um ITEM inteiro require ["a", "b"].contains("a") require !["ab"].contains("a") // "a" não é item da lista}10.3 Funções globais
Seção intitulada “10.3 Funções globais”min(a, b) e max(a, b)
Seção intitulada “min(a, b) e max(a, b)”check "min e max" { larguras = doc.pages.map { |p| p.width } // Reduzindo uma lista com each menor = 99999 doc.pages.each { |p| menor = min(menor, p.width) } print("página mais estreita:", menor, "pt")}Valor absoluto — essencial para comparar dimensões com tolerância.
check "abs" { const A4_LARGURA = 595.0 const TOLERANCIA = 5.0
doc.pages.each { |page| // "a diferença, para mais ou para menos, é menor que a tolerância" assert abs(page.width - A4_LARGURA) < TOLERANCIA, "página #{page.number} fora do A4: #{page.width}pt" }}round(x)
Seção intitulada “round(x)”Arredonda para o inteiro mais próximo. Útil para deixar as mensagens legíveis.
check "round" { doc.images.each { |img| // sem round: "217.4453125 DPI" — com round: "217 DPI" assert img.dpi >= 300, "imagem na página #{img.page_number}: #{round(img.dpi)} DPI" }
mb = struct::file_size() / 1024 / 1024 print("tamanho:", round(mb), "MB")}print(...)
Seção intitulada “print(...)”Imprime valores separados por espaço. Sai no stderr, então não polui o
relatório no stdout — dá para usar > relatorio.json sem misturar.
check "print" { print("documento:", doc.filename) print("páginas:", doc.page_count, "| fontes:", doc.fonts.length)
// Útil para investigar antes de escrever a validação definitiva doc.images.each { |img| print("imagem", img.width, "x", img.height, "@", round(img.dpi), "DPI") }}region(x, y, largura, altura [, nome])
Seção intitulada “region(x, y, largura, altura [, nome])”Cria uma região. Documentada no capítulo 2.
10.4 Padrões úteis
Seção intitulada “10.4 Padrões úteis”Contar quantos itens falham
Seção intitulada “Contar quantos itens falham”check "Contagem de problemas" { ruins = doc.images.filter { |i| i.dpi < 300 } assert ruins.length == 0, "#{ruins.length} de #{doc.images.length} imagens abaixo de 300 DPI"}Listar os itens que falharam na mensagem
Seção intitulada “Listar os itens que falharam na mensagem”check "Lista na mensagem" { // Encadeamentos ficam na mesma linha: o ponto precisa vir logo // após o valor anterior, sem quebra de linha no meio. problemas = doc.pages.filter { |p| !p.has_trim_box }.map { |p| p.number }
assert problemas.length == 0, "páginas sem TrimBox: #{problemas.join(", ")}"}Validar com tolerância
Seção intitulada “Validar com tolerância”function proximo(valor, alvo, tolerancia) { abs(valor - alvo) < tolerancia}
check "Com tolerância" { doc.pages.each { |page| assert proximo(page.width, 595.0, 2.0), "página #{page.number}: largura #{page.width}pt (esperado 595 ± 2)" }}Evitar erro em documento vazio
Seção intitulada “Evitar erro em documento vazio”check "Defensivo" { // O curto-circuito evita avaliar first() em lista vazia assert doc.pages.length == 0 || doc.pages.first().width > 0, "primeira página sem largura"}