<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marcelo Junior</title>
    <description>The latest articles on Forem by Marcelo Junior (@juneira).</description>
    <link>https://forem.com/juneira</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F339711%2F5a920e45-fa10-476b-95e4-04f1f94e5e49.jpeg</url>
      <title>Forem: Marcelo Junior</title>
      <link>https://forem.com/juneira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juneira"/>
    <language>en</language>
    <item>
      <title>[PT-BR] Shoryuken Vs Sidekiq</title>
      <dc:creator>Marcelo Junior</dc:creator>
      <pubDate>Mon, 20 Nov 2023 18:55:08 +0000</pubDate>
      <link>https://forem.com/juneira/pt-br-shoryuken-vs-sidekiq-3118</link>
      <guid>https://forem.com/juneira/pt-br-shoryuken-vs-sidekiq-3118</guid>
      <description>&lt;p&gt;Quando pensamos em processamento em background no mundo &lt;code&gt;Ruby&lt;/code&gt;, levamos em conta atualmente com algumas &lt;code&gt;Gems&lt;/code&gt; que fazem esse trabalho. Atualmente as que mais se destacam é a &lt;a href="https://github.com/ruby-shoryuken/shoryuken"&gt;Shoryuken&lt;/a&gt; e a &lt;a href="https://github.com/sidekiq/sidekiq"&gt;Sidekiq&lt;/a&gt;, e nesse post vamos ver quais são suas diferenças e quando usar cada uma delas.&lt;/p&gt;

&lt;p&gt;(Esse artigo leva em conta apenas o &lt;code&gt;Sidekiq&lt;/code&gt; em sua versão gratuita) &lt;/p&gt;

&lt;h3&gt;
  
  
  Sidekiq
&lt;/h3&gt;

&lt;p&gt;Visto que a &lt;code&gt;Gem&lt;/code&gt; mais velha é a &lt;code&gt;Sidekiq&lt;/code&gt;, é importante olharmos para ela primeiro e entender qual é a função que ela desempenha.&lt;/p&gt;

&lt;p&gt;Diferente da &lt;a href="https://github.com/resque/resque"&gt;Resque&lt;/a&gt;, a &lt;code&gt;Sidekiq&lt;/code&gt; veio com a ideia de processar os &lt;code&gt;jobs&lt;/code&gt; de forma concorrente usando &lt;code&gt;threads&lt;/code&gt;. Antes era necessário aumentar o número de processos, para conseguir processar mais jobs, de forma que era usado mais memória.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TIZrtBv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oy581fgqtsazji5eue9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TIZrtBv_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oy581fgqtsazji5eue9.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas também há semelhanças com o &lt;code&gt;Resque&lt;/code&gt;, uma delas é o uso do &lt;a href="https://redis.io/"&gt;Redis&lt;/a&gt; para armazenar e processar os jobs. Por ser um banco &lt;code&gt;in-memory&lt;/code&gt;, tanto a escrita como sua leitura são bem rápidas, já que essas operações serão feitas apenas sobre a &lt;strong&gt;memória RAM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Levando em conta esses pontos, porque usar o &lt;code&gt;Shoryuken&lt;/code&gt;? O que ele entrega, que o &lt;code&gt;Sidekiq&lt;/code&gt; não entrega (pelo menos na versão Free)?&lt;/p&gt;

&lt;h3&gt;
  
  
  Shoryuken
&lt;/h3&gt;

&lt;p&gt;A principal diferença entre o &lt;code&gt;Shoryuken&lt;/code&gt; e o &lt;code&gt;Sidekiq&lt;/code&gt; está no armazenamento e processamento dos jobs. O &lt;code&gt;Shoryuken&lt;/code&gt; usa o serviço &lt;a href="https://aws.amazon.com/pt/sqs/"&gt;SQS&lt;/a&gt; da &lt;strong&gt;AWS&lt;/strong&gt;, ou seja, não temos que configurar e manter uma instancia do &lt;code&gt;Redis&lt;/code&gt;, todo esse trabalho fica a cargo da &lt;strong&gt;AWS&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Por que usar o SQS?
&lt;/h4&gt;

&lt;p&gt;Segundo a própria &lt;strong&gt;AWS&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/pt_br/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-benefits.html"&gt;os beneficios de se usar o SQS&lt;/a&gt; são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Segurança&lt;/strong&gt;: você controla quem pode enviar e receber mensagens em uma fila do Amazon SQS. Você pode optar pela transmissão de dados sigilosos protegendo o conteúdo das mensagens em filas por meio da criptografia do lado do servidor (SSE) gerenciada pelo Amazon SQS ou das chaves de SSE gerenciadas no AWS Key Management Service (AWS KMS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Durabilidade&lt;/strong&gt;: para garantir a segurança de suas mensagens, o Amazon SQS as armazena em vários servidores. As filas comuns são compatíveis com a entrega de mensagens pelo menos uma vez, e as filas FIFO são compatíveis com o processamento de mensagens exatamente uma vez e com o modo de alto throughput.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Disponibilidade&lt;/strong&gt;: o Amazon SQS usa infraestrutura redundante para fornecer acesso altamente simultâneo às mensagens, além de alta disponibilidade para produzir e consumir mensagens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Escalabilidade&lt;/strong&gt;: o Amazon SQS pode processar cada solicitação em buffer de forma independente, escalando de forma transparente para lidar com qualquer aumento ou pico de carga sem nenhuma instrução de provisionamento.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Confiabilidade&lt;/strong&gt;: o Amazon SQS bloqueia suas mensagens durante o processamento, para que vários produtores possam enviar, e vários consumidores possam receber, mensagens ao mesmo tempo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Personalização&lt;/strong&gt;: suas filas não precisam ser exatamente iguais. Você pode definir um atraso padrão em uma fila, por exemplo. Você pode armazenar o conteúdo de mensagens maiores que 256 KB usando o Amazon Simple Storage Service (Amazon S3) ou o Amazon DynamoDB, com o Amazon SQS mantendo um ponteiro no objeto do Amazon S3, ou pode dividir uma mensagem grande em mensagens menores.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E o melhor, temos &lt;a href="https://aws.amazon.com/sqs/pricing/"&gt;1 milhão de requests grátis para cada mês de uso&lt;/a&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  Desempenho
&lt;/h4&gt;

&lt;p&gt;Assim como o &lt;code&gt;Sidekiq&lt;/code&gt;, o &lt;code&gt;Shoryuken&lt;/code&gt; também utiliza de threads para processar suas mensagens. Há um benchmarking de um &lt;a href="https://www.pablocantero.com/blog/2015/03/14/sidekiq-redis-vs-shoryuken-aws-sqs/"&gt;artigo&lt;/a&gt; que li, mostrando que há um pequena vantagem do &lt;code&gt;Sidekiq&lt;/code&gt; sobre o &lt;code&gt;Shoryuken&lt;/code&gt;, porém não acredito ser um ponto tão importante quando vamos escolher entre um dos dois.&lt;/p&gt;

&lt;h4&gt;
  
  
  Armazenamento
&lt;/h4&gt;

&lt;p&gt;Quando usamos o &lt;code&gt;Redis&lt;/code&gt; para armazenar os nossos &lt;code&gt;jobs&lt;/code&gt;, precisamos ter em mente que esse banco de dados PODE estar apenas na memória RAM. Falo "PODE", porque existe algumas &lt;a href="https://redis.io/docs/management/persistence/"&gt;features do &lt;code&gt;Redis&lt;/code&gt;&lt;/a&gt; que é possivel configurar-lo para que armazene o que está na &lt;code&gt;RAM&lt;/code&gt; para o disco rígido. Caso aconteça da instância que está rodando o &lt;code&gt;Redis&lt;/code&gt; morra, podemos perder jobs importantes que não foram processados.&lt;/p&gt;

&lt;p&gt;Já para o SQS não temos que nos preocupar com isso, poís é garantido pela AWS que não iremos perder de forma alguma nossas mensagens.&lt;/p&gt;

&lt;h4&gt;
  
  
  Escalabilidade
&lt;/h4&gt;

&lt;p&gt;Outro ponto que temos que levar em conta é a escalabilidade.&lt;/p&gt;

&lt;p&gt;Se houver um pico de usuário que não foi planejado anteriormente, o seu sistema está pronto para continuar atuando da mesma maneira em relação ao processamento em background?&lt;/p&gt;

&lt;p&gt;Quando usamos o &lt;code&gt;Redis&lt;/code&gt; para guardar nossos &lt;code&gt;jobs&lt;/code&gt;, temos que nos preocupar com isso.&lt;br&gt;
Já quando usamos o &lt;code&gt;SQS&lt;/code&gt; não é necessário, pois de novo, a AWS garante que irá atender todos os produtores e consumidores da fila, mesmo quando houver picos de acesso.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;A decisão entre &lt;code&gt;Shoryuken&lt;/code&gt; e &lt;code&gt;Sidekiq&lt;/code&gt; está mais atrelada a &lt;code&gt;Redis&lt;/code&gt; e &lt;code&gt;SQS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para decidir qual das duas &lt;code&gt;GEMs&lt;/code&gt; usar, deve-se levar em conta o quão importante é não perder o job que será enfileirado e processado.&lt;br&gt;
Além de também levar em conta de há hoje um time que irá conseguir dar manutenção necessária, para que no caso do &lt;code&gt;Redis&lt;/code&gt;, não tenha grandes problemas.&lt;/p&gt;

&lt;h4&gt;
  
  
  Referencias
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/pt_br/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-benefits.html"&gt;https://docs.aws.amazon.com/pt_br/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-benefits.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.appsignal.com/2022/02/15/delayed-job-vs-sidekiq-which-is-better.html"&gt;https://blog.appsignal.com/2022/02/15/delayed-job-vs-sidekiq-which-is-better.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sidekiq.org/"&gt;https://sidekiq.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ruby-shoryuken/shoryuken"&gt;https://github.com/ruby-shoryuken/shoryuken&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>gem</category>
      <category>aws</category>
    </item>
    <item>
      <title>Creating a Gem</title>
      <dc:creator>Marcelo Junior</dc:creator>
      <pubDate>Mon, 26 Jun 2023 11:33:08 +0000</pubDate>
      <link>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-part-3-2lhd</link>
      <guid>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-part-3-2lhd</guid>
      <description>&lt;h3&gt;
  
  
  Creating a Gem
&lt;/h3&gt;

&lt;p&gt;After compiling and testing our &lt;code&gt;C Extension&lt;/code&gt; for &lt;code&gt;Ruby&lt;/code&gt;, we can now create a Gem!&lt;br&gt;
First, we should create some folders to organize the project.&lt;/p&gt;

&lt;p&gt;See below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XG0AMQnU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1bh62ifej0xk3h27m2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XG0AMQnU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1bh62ifej0xk3h27m2g.png" alt="Image description" width="116" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second, create the file &lt;code&gt;lib/foo.rb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'foo/foo'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(You can create other classes inside this file if you desire.)&lt;/p&gt;

&lt;p&gt;And finally, create the file &lt;code&gt;foo.gemspec&lt;/code&gt; inside the root of the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Specification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"A SUMMARY"&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"A DESCRIPTION"&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authors&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"email@example.com"&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;files&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w[lib/foo.rb lib/foo/foo.so]&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;homepage&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://anylink.com"&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;license&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"MIT"&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extensions&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w[ext/foo/extconf.rb]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run on the root project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gem build foo.gemspec
gem &lt;span class="nb"&gt;install &lt;/span&gt;foo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test the gem you can open the &lt;code&gt;irb&lt;/code&gt; and past this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt;

&lt;span class="no"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;
&lt;span class="c1"&gt;# hello!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 Yeahhhh!!! We have a Gem!!! 🎉&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>gems</category>
    </item>
    <item>
      <title>Writing our C Extension</title>
      <dc:creator>Marcelo Junior</dc:creator>
      <pubDate>Wed, 21 Jun 2023 10:42:24 +0000</pubDate>
      <link>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-part-2-1be3</link>
      <guid>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-part-2-1be3</guid>
      <description>&lt;h3&gt;
  
  
  How to compile C code for use in the program Ruby?
&lt;/h3&gt;

&lt;p&gt;Write a &lt;a href="https://opensource.com/article/18/8/what-how-makefile"&gt;Makefile&lt;/a&gt; to compile this program as shared lib to a program &lt;code&gt;Ruby&lt;/code&gt; to use can be hard work, to solve this problem Ruby's core created the module &lt;a href="https://ruby-doc.org/stdlib-2.5.1/libdoc/mkmf/rdoc/MakeMakefile.html"&gt;MakeMakefile&lt;/a&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First: write a script in &lt;code&gt;Ruby&lt;/code&gt; to "make our MakeFile" named &lt;code&gt;extconf.rb&lt;/code&gt; on the same folder of program &lt;code&gt;C&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'mkmf'&lt;/span&gt;

&lt;span class="n"&gt;create_makefile&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;strong&gt;simple code&lt;/strong&gt; generates a &lt;code&gt;MakeFile&lt;/code&gt; to the file &lt;code&gt;foo.c&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Second: Run &lt;code&gt;ruby extconf.rb&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll find our Makefile in the current path! 🎉&lt;/p&gt;

&lt;p&gt;But... and the file &lt;code&gt;foo.c&lt;/code&gt;?&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing our C Extension
&lt;/h3&gt;

&lt;p&gt;See below basic skeleton of our C Extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"ruby.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Init_foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Your C code goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First &lt;code&gt;include&lt;/code&gt; the lib &lt;code&gt;ruby.h&lt;/code&gt; to use functions, constants... of &lt;code&gt;Ruby&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Second create a function that returns &lt;code&gt;void&lt;/code&gt;, named &lt;code&gt;Init_&lt;/code&gt; plus the name used in &lt;code&gt;extconf.rb&lt;/code&gt;. In this example &lt;code&gt;Init_foo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bingo! Our first C Extension is done!&lt;/p&gt;

&lt;p&gt;To see the shared lib compiled by this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ruby extconf.rb
$ make
$ ls
Makefile  extconf.rb  foo.c  foo.o  foo.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a &lt;code&gt;Class&lt;/code&gt; and a &lt;code&gt;Method&lt;/code&gt; to say "hello"?&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Class and Method to foo.c
&lt;/h3&gt;

&lt;p&gt;See below how &lt;code&gt;file.c&lt;/code&gt; turned out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"ruby.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="nf"&gt;rb_hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rb_str_new_cstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;rb_funcall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rb_mKernel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_intern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"puts"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Qnil&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Init_foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rb_define_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Greeting"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_cObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;rb_define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like the first part of this article, we'll define the class &lt;code&gt;Greeting&lt;/code&gt; using the function &lt;code&gt;rb_define_class&lt;/code&gt; inheriting from &lt;code&gt;Object&lt;/code&gt;. And we'll define the method of class &lt;code&gt;hello&lt;/code&gt; using &lt;code&gt;rb_define_singleton_method&lt;/code&gt; passing the function &lt;code&gt;rb_hello&lt;/code&gt; as a parameter.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;rb_hello&lt;/code&gt; should return &lt;code&gt;VALUE&lt;/code&gt; and receive as a parameter the class. This function transforms a &lt;code&gt;string&lt;/code&gt; of &lt;code&gt;C&lt;/code&gt; to a &lt;code&gt;string&lt;/code&gt; of &lt;code&gt;Ruby&lt;/code&gt; using the method &lt;code&gt;rb_str_new_cstr&lt;/code&gt;, then call method &lt;code&gt;puts&lt;/code&gt; of &lt;code&gt;Kernel&lt;/code&gt; through of function &lt;code&gt;rb_funcall(rb_mKernel, rb_intern("puts"), 1, str)&lt;/code&gt;. And finally returns &lt;code&gt;Qnil&lt;/code&gt;, the same &lt;code&gt;nil&lt;/code&gt; of &lt;code&gt;Ruby&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Ruby&lt;/code&gt; this code is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Greeting&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;
    &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt; &lt;span class="c1"&gt;# or puts "hello"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LET'S RUN IT!
&lt;/h3&gt;

&lt;p&gt;To test our work until here compile the C Extension again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ruby extconf.rb
$ make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open the &lt;code&gt;irb&lt;/code&gt; inside of folder of shared lib and run this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./foo'&lt;/span&gt;

&lt;span class="no"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;
&lt;span class="c1"&gt;# hello!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 🎉 YEAH! ITS DONE! 🎉 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;p&gt;Finally, we compile our C Extension! However, we don't create a Gem yet 🙄...&lt;/p&gt;

&lt;p&gt;In the next article, we'll make this!&lt;/p&gt;

&lt;p&gt;See you later 😀&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>gem</category>
    </item>
    <item>
      <title>Basic about Ruby C API</title>
      <dc:creator>Marcelo Junior</dc:creator>
      <pubDate>Tue, 20 Jun 2023 11:53:07 +0000</pubDate>
      <link>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-4h5a</link>
      <guid>https://forem.com/juneira/creating-a-gem-using-ruby-c-api-4h5a</guid>
      <description>&lt;h3&gt;
  
  
  Creating a Gem using Ruby C API
&lt;/h3&gt;

&lt;p&gt;Sometimes we want to use a lib built with &lt;code&gt;C&lt;/code&gt; language without any &lt;code&gt;Ruby&lt;/code&gt; version, to make this we'll find a gem that integrates the lib &lt;code&gt;C&lt;/code&gt; with &lt;code&gt;Ruby&lt;/code&gt;. But, how this Gem was built?&lt;/p&gt;

&lt;p&gt;In this article I'll show how to make this, using as an example the project &lt;a href="https://github.com/juneira/musicrb/tree/v0.0.0"&gt;musicrb&lt;/a&gt;, this Gem uses the lib of &lt;code&gt;C&lt;/code&gt; &lt;a href="https://www.videolan.org/vlc/index.pt_BR.html"&gt;vlc&lt;/a&gt; to play music on Ruby.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is possible to integrate Ruby and C?
&lt;/h3&gt;

&lt;p&gt;It's simple: &lt;code&gt;Ruby&lt;/code&gt; is built using &lt;code&gt;C&lt;/code&gt;, so we'll build a shared lib to the interpreter of &lt;code&gt;Ruby&lt;/code&gt; use.&lt;/p&gt;

&lt;p&gt;But do not trust in me, see the &lt;a href="https://github.com/ruby/ruby"&gt;repository of language&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic about Ruby C API
&lt;/h3&gt;

&lt;p&gt;Before starting to code our lib, we'll see some features in &lt;a href="http://silverhammermba.github.io/emberb/c/"&gt;Ruby C API&lt;/a&gt; that we will use (p.s.: this tutorial is very basic if you want deep in this theme, my recommendation is the book &lt;a href="https://www.amazon.com.br/Ruby-Under-Microscope-Illustrated-Internals/dp/1593275277"&gt;Ruby Under a Microscope&lt;/a&gt;). &lt;/p&gt;

&lt;h4&gt;
  
  
  VALUE
&lt;/h4&gt;

&lt;p&gt;See &lt;strong&gt;VALUE&lt;/strong&gt; as a pointer to a &lt;code&gt;Ruby's Object&lt;/code&gt;, since the &lt;code&gt;Ruby&lt;/code&gt; is dynamic this feature is required. Then &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Number&lt;/code&gt;, &lt;code&gt;Class&lt;/code&gt;, &lt;code&gt;Module&lt;/code&gt; ... are accessed and modified by &lt;code&gt;VALUE&lt;/code&gt; through functions of &lt;code&gt;Ruby C API&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is an example using &lt;code&gt;VALUE&lt;/code&gt; as a pointer to &lt;code&gt;String&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rb_str_new_cstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="no"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rb_sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pi = %f. %"&lt;/span&gt;&lt;span class="no"&gt;PRIsVALUE&lt;/span&gt;&lt;span class="s2"&gt;" inspected: %+"&lt;/span&gt;&lt;span class="no"&gt;PRIsVALUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;M_PI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="sr"&gt;/* pi = 3.141593. Hello, world! inspected: "Hello, world!" */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that isn't required to pass the type of VALUE to methods like a program&lt;code&gt;Ruby&lt;/code&gt;!&lt;/p&gt;

&lt;h4&gt;
  
  
  DEFINE
&lt;/h4&gt;

&lt;p&gt;The Gem &lt;code&gt;musicrb&lt;/code&gt; has a &lt;code&gt;class&lt;/code&gt; named &lt;code&gt;Music&lt;/code&gt;, and has two static methods: &lt;code&gt;play&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Define this &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;methods&lt;/code&gt; using &lt;code&gt;Ruby&lt;/code&gt; is very simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Music&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;
    &lt;span class="c1"&gt;# Implementation ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stop&lt;/span&gt;
    &lt;span class="c1"&gt;# Implementation ...&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code in &lt;code&gt;C&lt;/code&gt; will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Headers ...&lt;/span&gt;

&lt;span class="c1"&gt;// Global variables ...&lt;/span&gt;
&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;rb_cMusic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;VALUE&lt;/span&gt;
&lt;span class="nf"&gt;rb_music_stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;msc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Implementation ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;VALUE&lt;/span&gt;
&lt;span class="nf"&gt;rb_music_play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;msc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;VALUE&lt;/span&gt; &lt;span class="n"&gt;rpath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Implementation ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;Init_musicrb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;rb_cMusic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rb_define_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Music"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_cObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;rb_define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rb_cMusic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"play"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_music_play&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;rb_define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rb_cMusic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"stop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rb_music_stop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;rb_define_class&lt;/code&gt;: Define a class named "Music" that has a heritage with "Object".&lt;br&gt;
&lt;code&gt;rb_define_singleton_method&lt;/code&gt;: Define a singleton method to class "Music", in other words, a method of class. The last parameter of the function is the number of args.&lt;/p&gt;

&lt;p&gt;Again, don't trust me!&lt;br&gt;
See here the &lt;a href="https://github.com/juneira/musicrb/blob/v0.0.0/ext/musicrb/musicrb.c"&gt;code&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;p&gt;Okay, we already see the basics about the &lt;code&gt;Ruby C API&lt;/code&gt;, but how to compile and test this code?&lt;/p&gt;

&lt;p&gt;This post is already too long... I will follow up on the subject in the next article!&lt;/p&gt;

&lt;p&gt;Goodbye, see you soon!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>gem</category>
    </item>
    <item>
      <title>[Monkey Patch] Chamando o método original</title>
      <dc:creator>Marcelo Junior</dc:creator>
      <pubDate>Thu, 26 Mar 2020 14:02:35 +0000</pubDate>
      <link>https://forem.com/juneira/monkey-patch-chamando-o-metodo-original-2koa</link>
      <guid>https://forem.com/juneira/monkey-patch-chamando-o-metodo-original-2koa</guid>
      <description>&lt;p&gt;Mesmo que não seja uma pratica tão elegante e até perigosa, o &lt;a href="https://pt.stackoverflow.com/questions/285190/o-que-%C3%A9-monkey-patch"&gt;Monkey Patch&lt;/a&gt; é uma realidade para os programadores Ruby (on Rails). E por este motivo decidi escrever este artigo relatando um desafio que encontrei esses dias, e como resolvi o mesmo.&lt;/p&gt;

&lt;p&gt;O desafio encontrado foi: "Tratar a exceção que um método que uma gem levantava". Para isso eu precisava chamar o método antigo, e não sabia bem como fazer isso.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, a forma que eu encontrei foi a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClasseDaGem&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;metodo&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"ERROR!!!!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClasseDaGem&lt;/span&gt;
  &lt;span class="kp"&gt;alias_method&lt;/span&gt; &lt;span class="ss"&gt;:antigo_metodo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:metodo&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;metodo&lt;/span&gt;
    &lt;span class="k"&gt;begin&lt;/span&gt;
      &lt;span class="n"&gt;antigo_metodo&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt;
      &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s2"&gt;"Faça o que precisar aqui!"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso você tenha uma solução melhor, não deixe de comentar ✌&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>brasil</category>
      <category>portugues</category>
    </item>
  </channel>
</rss>
