<?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>DEV Community: olistik</title>
    <description>The latest articles on DEV Community by olistik (@olistik).</description>
    <link>https://dev.to/olistik</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%2F54900%2Fe375ca15-4073-4f90-833b-18f752b175b3.jpeg</url>
      <title>DEV Community: olistik</title>
      <link>https://dev.to/olistik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olistik"/>
    <language>en</language>
    <item>
      <title>Compiling Ruby 3.3 on OpenBSD 7.4</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Sun, 14 Jan 2024 18:14:18 +0000</pubDate>
      <link>https://dev.to/olistik/compiling-ruby-33-on-openbsd-74-5emn</link>
      <guid>https://dev.to/olistik/compiling-ruby-33-on-openbsd-74-5emn</guid>
      <description>&lt;p&gt;Resuming the work done for&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/olistik/a-naive-installation-of-ruby-and-rails-on-openbsd-4d50"&gt;https://dev.to/olistik/a-naive-installation-of-ruby-and-rails-on-openbsd-4d50&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to test the latest Ruby 3.3.0 on the latest OpenBSD 7.4 and here are the results.&lt;/p&gt;

&lt;p&gt;First of all, let's download the sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-LO&lt;/span&gt; https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;tar &lt;/span&gt;xvfz ruby-3.3.0.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ruby-3.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;libyaml&lt;/code&gt; dependency if you don't have it already:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;doas pkg_add libyaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the compilation so that it picks libyaml and it outputs the binaries in our &lt;code&gt;rubies&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ CONFIGURE_ARGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--with-libyaml-dir=/usr/local/lib"&lt;/span&gt; ./configure  &lt;span class="nt"&gt;--prefix&lt;/span&gt; ~/.rubies/3.3.0
&lt;span class="nv"&gt;$ &lt;/span&gt;make
&lt;span class="nv"&gt;$ &lt;/span&gt;make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the symlink for the current version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/rubies
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;current
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /home/&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.rubies/3.3.0/ current
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then check if everything works as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby &lt;span class="nt"&gt;-v&lt;/span&gt;
ruby 3.3.0 &lt;span class="o"&gt;(&lt;/span&gt;2023-12-25 revision 5124f9ac75&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;x86_64-openbsd7.4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>openbsd</category>
    </item>
    <item>
      <title>A naive installation of Ruby and Rails on OpenBSD</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Fri, 27 Aug 2021 16:21:24 +0000</pubDate>
      <link>https://dev.to/olistik/a-naive-installation-of-ruby-and-rails-on-openbsd-4d50</link>
      <guid>https://dev.to/olistik/a-naive-installation-of-ruby-and-rails-on-openbsd-4d50</guid>
      <description>&lt;p&gt;&lt;a href="https://unsplash.com/photos/Hq32VUY0xMg"&gt;image credits&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the environment we'll play with (just an excuse to use &lt;code&gt;neofetch&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnizoz3ed3eu9e86d9idw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnizoz3ed3eu9e86d9idw.png" alt="OpenBSD environment information as shown by the command  raw `neofetch` endraw " width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The packages are handy but I'd prefer to keep the installation within my home in order to make actions like &lt;code&gt;bundle install&lt;/code&gt; work without the need for super user permissions or custom configurations.&lt;/p&gt;

&lt;p&gt;Also, I don't mind reducing the number of indirection layers.&lt;/p&gt;

&lt;p&gt;First of all prepare the directory in which we'll install Ruby.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.rubies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we're doing this to avoid the need for the superuser.&lt;/p&gt;

&lt;p&gt;Then download the sources of the latest version (&lt;em&gt;3.0.2&lt;/em&gt;) and install them into our user directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-LO&lt;/span&gt; https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.2.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;tar &lt;/span&gt;xvfz ruby-3.0.2.tar.gz
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ruby-3.0.2
&lt;span class="nv"&gt;$ &lt;/span&gt;./configure &lt;span class="nt"&gt;--prefix&lt;/span&gt; ~/.rubies/3.0.2
&lt;span class="nv"&gt;$ &lt;/span&gt;make
&lt;span class="nv"&gt;$ &lt;/span&gt;make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For convenience, link the newly installed version with the "current" alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.rubies/3.0.2 &lt;span class="nv"&gt;$HOME&lt;/span&gt;/rubies/current
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;~/.profile&lt;/code&gt; and add &lt;code&gt;$HOME/.rubies/current/bin&lt;/code&gt; to the &lt;code&gt;$PATH&lt;/code&gt; so that the binaries will more easily be available in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/.rubies/current/bin:&lt;span class="nv"&gt;$HOME&lt;/span&gt;/bin:__the rest of the path list here__
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's our little precious:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ruby &lt;span class="nt"&gt;-v&lt;/span&gt;
ruby 3.0.2p107 &lt;span class="o"&gt;(&lt;/span&gt;2021-07-07 revision 0db68f0233&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;x86_64-openbsd6.9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nokogiri
&lt;/h2&gt;

&lt;p&gt;Using the same approach described for &lt;em&gt;FreeBSD&lt;/em&gt; in &lt;a href="https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries"&gt;https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries&lt;/a&gt; we'll install the &lt;code&gt;pkgconf&lt;/code&gt; package (note that the current user needs to be enabled for &lt;code&gt;doas&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;doas pkg &lt;span class="nb"&gt;install &lt;/span&gt;pkgconf
&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;nokogiri &lt;span class="nt"&gt;--platform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ruby &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--use-system-libraries&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A new dawn
&lt;/h2&gt;

&lt;p&gt;Time to test that the big boy works (picking "rails API only" to make things simpler):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;rails
&lt;span class="nv"&gt;$ &lt;/span&gt;rails new &lt;span class="nt"&gt;--api&lt;/span&gt; yolo
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;yolo
&lt;span class="nv"&gt;$ &lt;/span&gt;rails server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open another terminal (or the browser at &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;) and enjoy the view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwemcfrl15je4ulmfkip.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwemcfrl15je4ulmfkip.jpeg" alt="Two woman jumping happily on the street" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/87EqZAWN-v8"&gt;image credits&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>openbsd</category>
    </item>
    <item>
      <title>Poor man's file watcher</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Tue, 24 Aug 2021 22:35:42 +0000</pubDate>
      <link>https://dev.to/olistik/poor-man-s-file-watcher-5849</link>
      <guid>https://dev.to/olistik/poor-man-s-file-watcher-5849</guid>
      <description>&lt;p&gt;&lt;a href="https://unsplash.com/photos/L9EV3OogLh0"&gt;Image source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suppose you want to perform a certain action each time one or more files change, for example running a spec each time they're updated.&lt;/p&gt;

&lt;p&gt;You should definitely use something more polished like &lt;a href="https://github.com/guard/guard"&gt;Guard&lt;/a&gt; but you could also experiment with a "simpler" approach.&lt;/p&gt;

&lt;p&gt;First of all create the Ruby script &lt;code&gt;check_event.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="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="n"&gt;last_mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
&lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;path_parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;
  &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;path_parts&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="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;path_parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'_spec.rb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
  &lt;span class="c1"&gt;# Debounce: skip if another event has been notified less than a second ago.&lt;/span&gt;
  &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_mod&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="n"&gt;last_mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="sb"&gt;`rspec "&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;"`&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure the command &lt;code&gt;inotifywait&lt;/code&gt; is installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;inotify-tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then you can combine &lt;code&gt;inotifywait&lt;/code&gt; with our Ruby script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;inotifywait &lt;span class="nt"&gt;--monitor&lt;/span&gt; &lt;span class="nt"&gt;--event&lt;/span&gt; modify &lt;span class="nt"&gt;--recursive&lt;/span&gt; ./spec | ruby check_event.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: I added a debounce in the Ruby script. This is because a &lt;em&gt;modify&lt;/em&gt; event is called twice upon file save (tested with Vim on Ubuntu).&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>linux</category>
    </item>
    <item>
      <title>Delete all untracked files in git</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Mon, 23 Aug 2021 19:50:24 +0000</pubDate>
      <link>https://dev.to/olistik/delete-all-untracked-files-in-git-4gng</link>
      <guid>https://dev.to/olistik/delete-all-untracked-files-in-git-4gng</guid>
      <description>&lt;p&gt;Suppose that you've just done a &lt;code&gt;git checkout -f&lt;/code&gt; to cleanup your local modifications.&lt;/p&gt;

&lt;p&gt;New files added will slip out of the previous command, because they're treated by git as "untracked".&lt;/p&gt;

&lt;p&gt;Here's a one-liner to get rid of these little fellas (requires a Ruby interpreter, because I &amp;lt;3 Ruby):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--untracked-files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;all &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--no-column&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--short&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;ruby &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"puts STDIN.read.lines.map(&amp;amp;:split).map(&amp;amp;:last).join(' ')"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8uxe8ktxwa6ybt6a7hf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8uxe8ktxwa6ybt6a7hf.jpeg" alt="Done" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/32aK4c8Iekc"&gt;Image source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update: as &lt;a class="mentioned-user" href="https://dev.to/kwstannard"&gt;@kwstannard&lt;/a&gt; rightfully pointed out in the comments, there's also the prettier &lt;code&gt;git-clean&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>oneliner</category>
      <category>shell</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Dealing with the lifecycle of a Tempfile</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Fri, 23 Jul 2021 14:50:15 +0000</pubDate>
      <link>https://dev.to/olistik/dealing-with-the-lifecycle-of-a-tempfile-1lfk</link>
      <guid>https://dev.to/olistik/dealing-with-the-lifecycle-of-a-tempfile-1lfk</guid>
      <description>&lt;p&gt;When dealing with &lt;code&gt;Tempfile&lt;/code&gt;s in Ruby it's important to remember that when a tempfile object gets deallocated, the referenced file gets deleted as well.&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;'tempfile'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;
  &lt;span class="no"&gt;Tempfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "/tmp/20210723-30107-1h52x7" &lt;/span&gt;

&lt;span class="c1"&gt;# Soon after:&lt;/span&gt;

&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# But wait for it..&lt;/span&gt;

&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; false &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>tempfile</category>
    </item>
    <item>
      <title>Playing with execution flows in Ruby</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Fri, 30 Apr 2021 17:05:11 +0000</pubDate>
      <link>https://dev.to/olistik/playing-with-execution-flows-in-ruby-5907</link>
      <guid>https://dev.to/olistik/playing-with-execution-flows-in-ruby-5907</guid>
      <description>&lt;p&gt;Let's define a simple &lt;em&gt;Result&lt;/em&gt; class:&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;Result&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="vi"&gt;@success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="vi"&gt;@data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&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;success?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="vi"&gt;@success&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&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;error?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;success?&lt;/span&gt;&lt;span class="p"&gt;;&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;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="vi"&gt;@data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;end&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;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;end&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&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;and then a &lt;em&gt;Flow&lt;/em&gt; class:&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;Flow&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:tasks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:result&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;tasks: &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&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;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;task&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;call&lt;/span&gt;
    &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&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;task&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kind_of?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;result&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;We can now do some interesting things such as:&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="n"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'#1'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'#2'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'#3 (error)'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'#4'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;RuntimeError: foo&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>flow</category>
    </item>
    <item>
      <title>Configure a custom Git repository on Netlify</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Fri, 21 Feb 2020 10:43:06 +0000</pubDate>
      <link>https://dev.to/olistik/configure-a-custom-git-repository-on-netlify-2nj8</link>
      <guid>https://dev.to/olistik/configure-a-custom-git-repository-on-netlify-2nj8</guid>
      <description>&lt;p&gt;My personal web site (&lt;a href="https://olisti.co"&gt;https://olisti.co&lt;/a&gt;) is a Gatsby.js project I used to serve publicly through &lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt; but this required me to use Github.&lt;/p&gt;

&lt;p&gt;Since I have my own Gitlab instance (&lt;a href="https://source.olisti.co"&gt;https://source.olisti.co&lt;/a&gt;) I wanted to configure Netlify's CI to point to my Gitlab repository instead.&lt;/p&gt;

&lt;p&gt;After a few attempts, I discovered that it's currently not possible to update the repository URL via:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the web UI: since it doesn't provide the option to specify a self-hosted Gitlab instance or to specify a manual Git URL.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;netlify api updateSite&lt;/code&gt; since passing a &lt;code&gt;build_settings&lt;/code&gt; object doesn't change the remote configuration, at least for the &lt;code&gt;repo_url&lt;/code&gt; attribute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to delete and recreate the Netlify site and configure it with &lt;a href="https://cli.netlify.com/"&gt;netlify-cli&lt;/a&gt; specifying these parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;λ netlify sites:create &lt;span class="nt"&gt;--manual&lt;/span&gt; &lt;span class="nt"&gt;--with-ci&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;--with-ci&lt;/code&gt; does the trick since it allows to specify the ssh URL of the Git repository.&lt;/p&gt;

&lt;p&gt;One last hiccup has been while trying to provision the Let's Encrypt SSL certificate. A worrying error message showed up even though the required checks were passing.&lt;/p&gt;

&lt;p&gt;It eventually went away after, I suppose, their local cache expired.&lt;/p&gt;

&lt;p&gt;And now that I know this, I can import my other repositories. ;-)&lt;/p&gt;

</description>
      <category>git</category>
      <category>netlify</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>Resuscitating my personal website 🧟‍♂️</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Thu, 20 Feb 2020 00:27:02 +0000</pubDate>
      <link>https://dev.to/olistik/resuscitating-my-personal-website-3mf6</link>
      <guid>https://dev.to/olistik/resuscitating-my-personal-website-3mf6</guid>
      <description>&lt;p&gt;It was the time.&lt;/p&gt;

&lt;p&gt;My old personal website was getting so old that it contained even the link to my Google+ profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr6e6sp1166anxwwfu22.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdr6e6sp1166anxwwfu22.jpg" alt="Are you from the past?!" width="400" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I could have kept it that way..&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr2ue8sngzpkzs7dlco51.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr2ue8sngzpkzs7dlco51.gif" alt="Cap says no" width="498" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.. but instead I finally took the occasion to play with &lt;a href="https://nostalgic-css.github.io/NES.css/"&gt;NES.css&lt;/a&gt; and &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby.js&lt;/a&gt;, adding a sprinkle of ✨CSS Grid✨.&lt;/p&gt;

&lt;p&gt;Thanks to GitHub and Netlify's hosting 🎩 the result is &lt;a href="//olisti.co"&gt;https://olisti.co&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's the &lt;a href="https://source.olisti.co/olistik/me"&gt;source code&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>nescss</category>
    </item>
    <item>
      <title>My minimalistic zsh prompt</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Wed, 19 Feb 2020 10:12:34 +0000</pubDate>
      <link>https://dev.to/olistik/my-minimalistic-zsh-prompt-243f</link>
      <guid>https://dev.to/olistik/my-minimalistic-zsh-prompt-243f</guid>
      <description>&lt;p&gt;In &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PROMPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{9}λ%f "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✨🎩✨&lt;/p&gt;

</description>
      <category>zsh</category>
      <category>prompt</category>
      <category>minimalism</category>
    </item>
    <item>
      <title>Experimenting simpler execution flows in Ruby</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Mon, 03 Feb 2020 09:50:40 +0000</pubDate>
      <link>https://dev.to/olistik/experimenting-simpler-execution-flows-in-ruby-25fc</link>
      <guid>https://dev.to/olistik/experimenting-simpler-execution-flows-in-ruby-25fc</guid>
      <description>&lt;p&gt;I created the gem &lt;a href="https://source.olisti.co/olistik/mu-result"&gt;Mu::Result&lt;/a&gt; because I feel the need to pass &lt;em&gt;Result objects&lt;/em&gt; instead of raw values.&lt;/p&gt;

&lt;p&gt;This allows me to write this kind of 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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;author_id&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://foo.com/posts/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&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;result&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt;
  &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;

  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://foo.com/authors/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&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;result&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt;

  &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;
  &lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;post: &lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;post_id: &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author_id: &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:network_error&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Some troubles in the network'&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:bad_request&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Maybe a malformed request'&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:forbidden&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Check your credentials'&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:not_found&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'They are gone, Jim'&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Generic errors'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"The post is: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with some wins like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it's relatively easy to propagate errors without relying on exceptions;&lt;/li&gt;
&lt;li&gt;there's a common API to handle richer return values;&lt;/li&gt;
&lt;li&gt;pattern matching can be performed with a simple case statement against result's &lt;code&gt;code&lt;/code&gt; attribute;&lt;/li&gt;
&lt;li&gt;no big boilerplates involved as &lt;code&gt;Mu::Result&lt;/code&gt; is really tiny.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdn0j2wur4ffqw0omdsuw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdn0j2wur4ffqw0omdsuw.gif" alt="FTW" width="320" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet, I feel it can be improved even further. 🤓&lt;/p&gt;

&lt;p&gt;Taking heavy inspiration from &lt;a href="https://dry-rb.org/gems/dry-monads/1.0/do-notation/"&gt;dry-rb's do notation&lt;/a&gt; here's a draft implementation I came up:&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;'mu/result'&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Mu&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Flow&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;do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&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;step&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error?&lt;/span&gt;

        &lt;span class="n"&gt;step&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;def&lt;/span&gt; &lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Mu&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&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;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Mu&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&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;Flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Mu&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&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;Everyday code can use it this way:&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="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mu&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Flow&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;logic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="no"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="no"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;code!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:too_low&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="n"&gt;magic_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="no"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;magic_number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:wow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;magic_number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
  &lt;span class="n"&gt;magic_number&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# simpler way with the helper:&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:logic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"result: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# result: #&amp;lt;Mu::Result::BaseResult:0x00007fd3d8027520 @code=:wow, @data=81&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# or more explicitly:&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Mu&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:logic&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"result: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# result: #&amp;lt;Mu::Result::BaseResult:0x00007fd3d8027160 @code=:ok, @data=16&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example is contrived but it shows that there's no need to write explicit returns for error results anymore.&lt;/p&gt;

&lt;p&gt;The implementation of &lt;code&gt;Mu::Flow&lt;/code&gt; aims to remain tiny.&lt;/p&gt;

&lt;p&gt;I'm still experimenting with this approach to see whether it produces a tangible gain or not. 🧐&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Team Renovation Proposals</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Sun, 02 Feb 2020 21:10:53 +0000</pubDate>
      <link>https://dev.to/olistik/team-renovation-proposals-4o9e</link>
      <guid>https://dev.to/olistik/team-renovation-proposals-4o9e</guid>
      <description>&lt;p&gt;&lt;em&gt;(This is a &lt;a href="https://olistik.svbtle.com/team-renovation-proposals"&gt;post&lt;/a&gt; I made 5 years ago on my old &lt;a href="https://svbtle.com"&gt;svbtle&lt;/a&gt; account. Some links might not work and I will probably update this content in the near future.)&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens if we invest in developing our people and then they leave the company?&lt;/p&gt;

&lt;p&gt;What happens if we don’t, and they stay?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Rationale
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Developers are the most valuable assets of the Company.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Everything I’ve written is highly influenced by my past experiences and readings. Several kudos to &lt;a href="http://37signals.com/"&gt;37 Signals&lt;/a&gt; for their amazing books (&lt;a href="http://37signals.com/rework/"&gt;Rework&lt;/a&gt; and &lt;a href="http://37signals.com/remote/"&gt;Remote&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Proposals
&lt;/h2&gt;

&lt;p&gt;The following is a list of proposals that can’t nor shouldn’t be imposed.&lt;br&gt;
They shouldn’t be implemented at the same time as well. Things need to roll out incrementally.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The direction you’re taking is more important than your current position.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Economy is by definition the management of scarce resources and we all face constraints on daily basis, so don’t consider the following as must­-to­have since day 1. Start by applying the right mentality and try to introduce, in the best possible way for your use case, some of these proposals. Some of them are actually very cheap to adopt.&lt;/p&gt;

&lt;p&gt;Also, give them a honest try and don’t let any previous attempts make you think these are not worthwhile.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pair Programming&lt;/li&gt;
&lt;li&gt;20% Projects&lt;/li&gt;
&lt;li&gt;Dev Blog&lt;/li&gt;
&lt;li&gt;Fight Workaholism&lt;/li&gt;
&lt;li&gt;Company’s Brand, Public Team Pages, Social Presence&lt;/li&gt;
&lt;li&gt;Tech Events Presence&lt;/li&gt;
&lt;li&gt;Embrace Remote Working&lt;/li&gt;
&lt;li&gt;Invest on Innovation&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
   1. Pair Programming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Pair programming is an agile software development technique in which two programmers work together at one workstation. One, the driver, writes code while the other, the observer or navigator, reviews each line of code as it is typed in. The two programmers switch roles frequently.” ­ &lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Increases Developers Skills&lt;/li&gt;
&lt;li&gt;Increases Design Quality&lt;/li&gt;
&lt;li&gt;Helps Quality Assurance and decreases the production of bugs&lt;/li&gt;
&lt;li&gt;Helps Team Building&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. 20% Projects
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“We encourage our employees, in addition to their regular projects, to spend 20% of their time working on what they think will most benefit Google. This empowers them to be more creative and innovative. Many of our significant advances have happened in this manner. For example, AdSense for content and Google News were both prototyped in “20% time.” Most risky projects fizzle, often teaching us something. Others succeed and become attractive businesses.” &lt;a href="http://investor.google.com/corporate/2004/ipo-founders-letter.html"&gt;Google’s 2004 Founders’ IPO Letter&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When developers can’t improve their skills they feel like stagnating, they start to lose faith in the project and, worst of all, in the Company itself.&lt;/p&gt;

&lt;p&gt;Sometimes they’d prefer to dive deep into some technical issues encountered during the development of a project instead of hopping from a project to another without having enough time to collect the necessary experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are some people that have 10 years of experience, others that have 1 year repeated 10 times.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;More often than not they simply want to experiment with a crazy/useful idea that can potentially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;turn into a profitable business&lt;/li&gt;
&lt;li&gt;improve the current communication or work flow&lt;/li&gt;
&lt;li&gt;improve current client work&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Dev blog
&lt;/h2&gt;

&lt;p&gt;Developers should be encouraged to write technical posts on a blog the Company makes available.&lt;br&gt;
This helps the developers to improve their communication skills and to gain peer recognition.&lt;/p&gt;

&lt;p&gt;A by product of this activity is that the Company itself gains popularity by the tech community and this also helps to attract skilled developers.&lt;br&gt;
Some examples of companies providing a developer’s blog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://googledevelopers.blogspot.it/"&gt;Google Developers Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.facebook.com/blog/"&gt;Facebook Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.twitter.com/blog"&gt;The Twitter Developer Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dropbox.com/developers/blog"&gt;Dropbox Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://devblog.blackberry.com/"&gt;Inside BlackBerry Developer Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.mikamai.com/"&gt;Mikamayhem&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Fight Workaholism
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Always leave office on time
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Work is &lt;strong&gt;a never ending process&lt;/strong&gt;. It can never be completed.&lt;/li&gt;
&lt;li&gt;Interest of a client is important, &lt;strong&gt;so is your family&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If you fail in your life, neither your boss nor client will offer you a helping hand; &lt;strong&gt;your family and friends will&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Life is not only about work, office and client. &lt;strong&gt;There is more to life.&lt;/strong&gt; You need time to socialize, entertain, relax and exercise. &lt;strong&gt;Don’t let life be meaningless.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A person who stays late at the office &lt;strong&gt;is not a hardworking person&lt;/strong&gt;. Instead he/she is a fool who does not know how to manage work within the stipulated time. He/She is a loser who does not have a personal or social life. He/She is inefficient and incompetent in his work.&lt;/li&gt;
&lt;li&gt;You did not study hard and struggle in life to become &lt;strong&gt;a machine&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If your boss forces you to work late, &lt;strong&gt;he/she may be ineffective and have a meaningless life too&lt;/strong&gt;; so forward this him/her.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Leaving Office On Time
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Efficient&lt;/li&gt;
&lt;li&gt;Good Social Life&lt;/li&gt;
&lt;li&gt;Quality Family Life&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Leaving Office Late
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inefficient &amp;amp; Incompetent&lt;/li&gt;
&lt;li&gt;No Social Life&lt;/li&gt;
&lt;li&gt;Less Family Time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://sphotos-d.ak.fbcdn.net/hphotos-ak-ash3/551438_10151454281709711_1512364673_n.jpg"&gt;source&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Company’s Brand, Public Team Pages, Social Presence
&lt;/h2&gt;

&lt;p&gt;Customers are highly influenced by how a Company presents itself and value a lot the human factor.&lt;br&gt;
Knowing the people behind the Company’s name, effectively seeing their faces, helps the Company make a connection to the customers.&lt;br&gt;
Developers are also happy to be considered as part of the family.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Would you be happy if your girlfriend/boyfriend is afraid of speaking about you to her/his friends?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is accomplished by providing a cool About Us page (possibly combined with a Team page).&lt;/p&gt;

&lt;p&gt;The appearance of solidity of the Company also depends on its ability to communicate with its customers and with their broader potential audience as well (some of them might be considered potential customers).&lt;/p&gt;

&lt;p&gt;The Company’s blog (i.e. &lt;a href="http://37signals.com/svn"&gt;Signal vs. Noise by 37 Signals&lt;/a&gt;) is one of the central places where the Company publicily states its awesomness.&lt;/p&gt;

&lt;p&gt;Don’t forget to write frequently stuff that matters and to spread every post across your online accounts (i.e. Facebook, Twitter, Google+ and Linkedin).&lt;/p&gt;

&lt;p&gt;Your very same developers will look forward to sponsor autonomously your online presence.&lt;/p&gt;

&lt;p&gt;To wrap things up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Abouts Us&lt;/em&gt; page&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Our Team&lt;/em&gt; page&lt;/li&gt;
&lt;li&gt;the Company’s Blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some examples of &lt;em&gt;About Us&lt;/em&gt; pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/about/team"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://37signals.com/svn/writers/"&gt;37 Signals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nebulab.it/about-us"&gt;Nebulab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.adaptivepath.com/about/"&gt;Adaptive Path&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.salemtownboardco.com/pages/about-us"&gt;Salem Town&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://teamepiphany.com/theteam/"&gt;Team Epiphany&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://harbr.co/heartbeat/"&gt;Harbr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Tech Events Presence
&lt;/h2&gt;

&lt;p&gt;Make your developers upgrade their skills by encouraging them to join tech related conferences and events.&lt;br&gt;
Try to tag your Company’s name to these events as well as &lt;em&gt;hackatons&lt;/em&gt;, for example via sponsorships and by hosting some events in your own offices.&lt;br&gt;
Other developers will know your name, and will be attracted to you.&lt;/p&gt;

&lt;p&gt;Tech companies will consider your company as a reference for the technologies your name is associated with.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Embrace Remote Work
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;As an employer, restricting your hiring to a small geographic region means you’re not getting the best people you can. As an employee, restricting your job search to companies within a reasonable commute means you’re not working for the best company you can. &lt;a href="http://37signals.com/remote/"&gt;Remote&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsew4dcu3v1b0d85q6ylx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsew4dcu3v1b0d85q6ylx.png" alt="Cover of the book Rework" width="800" height="1207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Invest on Innovation
&lt;/h2&gt;

&lt;p&gt;Don’t ever stop to move, your developers want to keep up with technology advances so you should too.&lt;br&gt;
This also helps you to differentiate your offerings and to be ready to catch up with the new competitors that will, without any doubt, start &lt;em&gt;by default&lt;/em&gt; to use the new opportunities.&lt;/p&gt;

&lt;p&gt;Nothing lasts forever, so do programming languages and frameworks.&lt;/p&gt;

&lt;p&gt;If you stick only with one programming language (be it PHP or Java), you’re already losing some opportunities.&lt;br&gt;
Nowadays, the cool kids on the block are Ruby, Node.js, Go and some purely functional programming languages. Some of them are based on the JVM.&lt;br&gt;
You should always strive to keep up with the state of the art, no less.&lt;br&gt;
You can’t innovate if you stay behind this line.&lt;br&gt;
If you don’t allocate enough time to experiment (for example, see &lt;em&gt;20% Projects&lt;/em&gt;), you won’t ever start using the new available stuff and you will slowly and inadvertently slow down your efficiency becoming the old Mammuth Companies you were mocking when you started.&lt;/p&gt;

</description>
      <category>growth</category>
    </item>
    <item>
      <title>Scratch Your Own Itch (Ruby edition)</title>
      <dc:creator>olistik</dc:creator>
      <pubDate>Sun, 02 Feb 2020 17:55:54 +0000</pubDate>
      <link>https://dev.to/olistik/scratch-your-own-itch-ruby-edition-17aj</link>
      <guid>https://dev.to/olistik/scratch-your-own-itch-ruby-edition-17aj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If you feel perfectly comfortable using a tool it means that you haven't used it enough. - me&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is why I'm creating some tools (Ruby gems) to help me feel more comfortable when developing software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://source.olisti.co/olistik/mu-result"&gt;Scratch&lt;/a&gt; 👏 &lt;a href="https://source.olisti.co/olistik/mu-json"&gt;your&lt;/a&gt; 👏 &lt;a href="https://source.olisti.co/olistik/mu-rest-client"&gt;own&lt;/a&gt; 👏 &lt;a href="https://source.olisti.co/olistik/mu-hash"&gt;itch&lt;/a&gt; 👏.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fse7u8tfe7cmsm914keyk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fse7u8tfe7cmsm914keyk.gif" alt="Comfy gif here" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

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