Modificando o $stdout com o uso de um método
Tags: beginners, tutorial, rails, programming
Published: 2023-12-06 01:00:09

Antes de iniciarmos com o método, devemos lembrar dos 3 caminhos de redirecionamento de dados que o nosso terminal pode nos oferecer.
**Entre eles temos:**

**`stdin`**
Que fornece o padrão de dados que o nosso terminal vai **receber**

**`stdout`**
Que fornece o padrão de dados que o nosso terminal vai **enviar**

**`stderr`**
Que fornece o padrão de redirecionamento de **erros** que o nosso terminal vai nos levar

> Vale lembrar que esta lógica de redirecionamento é um padrão para todos os tipos de terminais.

---

Dito isso, iremos direto ao ponto do método. Utilizado em um arquivo helper de uma spec, o método nessa situação tinha o objetivo de modificar a saída de um método de classe para que o terminal interpretasse como uma string, em outras palavras, sempre que o método fosse utilizado em um valor, o terminal extrairia esse valor e "transformaria" em uma string.

**O método utilizado:**

```
def capture_stdout
   original_stdout = $stdout
   $stdout = StringIO.new
YIELD
   $stdout.string
ENSURE
   $stdout = original_stdout
end
```

>` $stdout` é uma variável global que vem junto com o console do ruby, o console do ruby traz outras variáveis globais sempre que ele é executado, assim como as palavras-chave `YIELD` e `ENSURE`

**Explicando passo a passo de como o método capture_stdout funciona**
- Para não modificar outras funcionalidades que estão dentro do nosso projeto, salvaremos a saída original do nosso console na variável original_stdout, que será usada mais tarde pelo nosso método.
- Em seguida definimos que a saída (`$stdout`) será capturada e modificada para uma string, ao utilizarmos a instância de classe `StringIO.new`

> **O que á a classe StringIO**
> Primeiramente IO se refere a input e output, Esta classe pode ser utilizada para capturar a saída de um valor, e modificar ele para que tenha o comportamento de um arquivo, segue um exemplo de como podemos utiliza-lo:
> ```
> minha_string = StringIO.new(“Esta é a minha string”)
> minha_string.puts “ E esse é meu put”
> puts.io.string
> => “Esta é a minha string /nE esse é meu put/n”
```

>_Minha string poderá ser manipulada com métodos get, put .. pois agora ela tem o comportamento de um "arquivo"_

**Retomando aos passos do nosso método**

`Bloco YIELD`
Por aqui definimos a saída do nosso método `capture_stdout`, neste bloco queremos que todo `$stdout` (Saída padrão do console) nos devolva seu valor em formato de string com a utilização do método `.string`

`Bloco ENSURE`
Por final uma das partes mais importantes do nosso método inteiro, vamos reutilizar a variável definida no começo, para que toda vez que utilizamos o nosso método, sua saída seja exatamente a mesma antes de entrar no método `capture_stdout`.

> **Lembrando que:**
> Tanto o `YIELD` quanto o `ENSURE`, são palavras-passe já pré definidas no ruby, que resumindo se comportam da seguinte forma:

> `YIELD:` Executa determinado bloco de código, para reproduzir algum valor esperado que será retornado pelo método.
>` ENSURE:` Sempre executará um bloco do código quando o método for finalizado, muito utilizado para fazer um certo **“backup”** do que foi modificado pelo método.

**Considerações finais**
Cada situação vai precisar que o método seja modificado, o método em questão só precisava modificar a saída para uma string, para que ao final de tudo um arquivo de testes comparasse essa saída com um expect que também era uma string.