<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Vinicius Rocha</title>
    <link>https://viniciusrocha.com/</link>
    <description>Recent content on Vinicius Rocha</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 12 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://viniciusrocha.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Zen of Python</title>
      <link>https://viniciusrocha.com/posts/the-zen-of-python/</link>
      <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/the-zen-of-python/</guid>
      <description>&lt;h2 id=&#34;the-easter-egg&#34;&gt;The Easter Egg&lt;/h2&gt;&#xA;&lt;p&gt;Run &lt;code&gt;import this&lt;/code&gt; in any Python interpreter and you get 19 aphorisms written by Tim Peters in 1999, baked into the language as an Easter egg:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Python 3.14.5 (tags/v3.14.5:5607950, May 10 2026, 10:43:50)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &amp;#34;help&amp;#34;, &amp;#34;copyright&amp;#34;, &amp;#34;credits&amp;#34; or &amp;#34;license&amp;#34; for more information.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt;&amp;gt;&amp;gt; import this&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The Zen of Python, by Tim Peters&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Beautiful is better than ugly.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Explicit is better than implicit.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Simple is better than complex.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Complex is better than complicated.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Flat is better than nested.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sparse is better than dense.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Readability counts.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Special cases aren&amp;#39;t special enough to break the rules.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Although practicality beats purity.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Errors should never pass silently.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unless explicitly silenced.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In the face of ambiguity, refuse the temptation to guess.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;There should be one-- and preferably only one --obvious way to do it.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Although that way may not be obvious at first unless you&amp;#39;re Dutch.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Now is better than never.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Although never is often better than *right* now.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If the implementation is hard to explain, it&amp;#39;s a bad idea.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If the implementation is easy to explain, it may be a good idea.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Namespaces are one honking great idea -- let&amp;#39;s do more of those!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;behind-the-poem&#34;&gt;Behind the Poem&lt;/h2&gt;&#xA;&lt;p&gt;The poem predates PEP 20; it circulated on the &lt;code&gt;comp.lang.python&lt;/code&gt; mailing list years before Guido van Rossum formalized it. The &lt;a href=&#34;https://github.com/python/cpython/blob/main/Lib/this.py&#34;&gt;source for the &lt;code&gt;this&lt;/code&gt; module&lt;/a&gt; is itself a wink: the poem is stored as a ROT-13-encoded string and decoded at import time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Spinel: Matz&#39;s Native Compiler for Ruby</title>
      <link>https://viniciusrocha.com/posts/spinel-matzs-native-compiler-for-ruby/</link>
      <pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/spinel-matzs-native-compiler-for-ruby/</guid>
      <description>&lt;p&gt;Yukihiro &amp;ldquo;Matz&amp;rdquo; Matsumoto, the creator of Ruby, is working on &lt;a href=&#34;https://github.com/matz/spinel&#34;&gt;Spinel&lt;/a&gt; — an ahead-of-time (AOT) compiler that transforms Ruby source code into standalone native executables. He presented it at &lt;a href=&#34;https://rubykaigi.org/2026/&#34;&gt;RubyKaigi 2026&lt;/a&gt; with a live demonstration, and the results are impressive: &lt;strong&gt;11.6x faster&lt;/strong&gt; than miniruby across benchmarks, with computation-heavy workloads reaching 24–87x speedups.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;&#xA;&lt;p&gt;Spinel&amp;rsquo;s compilation pipeline has three stages:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Parsing&lt;/strong&gt; — a C binary (&lt;code&gt;spinel_parse&lt;/code&gt;) uses &lt;a href=&#34;https://github.com/ruby/prism&#34;&gt;libprism&lt;/a&gt; to parse Ruby and serialize the AST.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Code generation&lt;/strong&gt; — a self-hosted Ruby binary (&lt;code&gt;spinel_codegen&lt;/code&gt;) performs whole-program type inference and generates optimized C.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Compilation&lt;/strong&gt; — a standard C compiler produces a standalone binary with no runtime dependencies beyond libc and libm.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The self-hosting part is the most interesting detail. The compiler backend is a 21,000-line Ruby file that Spinel itself compiles into a native binary. The compiler compiles itself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging TurboTax with Claude Code</title>
      <link>https://viniciusrocha.com/posts/debugging-turbotax-with-claude-code/</link>
      <pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/debugging-turbotax-with-claude-code/</guid>
      <description>&lt;div class=&#34;tldr-callout&#34;&gt;&#xA;  &lt;span class=&#34;tldr-label&#34;&gt;TL;DR&lt;/span&gt;&#xA;  &lt;div class=&#34;tldr-content&#34;&gt;&lt;ul&gt;&#xA;&lt;li&gt;Claude Code can analyze HAR files — browser network traffic exports — to debug real-world problems quickly.&lt;/li&gt;&#xA;&lt;li&gt;TurboTax was detecting my browser timezone and inferring I was in Canada, redirecting me to the Canadian login page.&lt;/li&gt;&#xA;&lt;li&gt;One prompt was enough to identify the root cause and get actionable steps to fix it.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;claude-code-as-a-daily-tool&#34;&gt;Claude Code as a daily tool&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://claude.ai/code&#34;&gt;Claude Code&lt;/a&gt; can be a powerful companion for everyday tasks, especially ones that involve large amounts of data to analyze. I use it every day as part of my job, and I have been finding more ways to bring it into my daily life beyond work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Notes on: Ruby Is the Best Language for Building AI Apps</title>
      <link>https://viniciusrocha.com/posts/notes-on-ruby-is-the-best-language-for-building-ai-apps/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/notes-on-ruby-is-the-best-language-for-building-ai-apps/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://paolino.me/ruby-is-the-best-language-for-ai-apps/&#34;&gt;Carmine Paolino&lt;/a&gt; makes a compelling case that Ruby is the best language for building AI applications in 2026 — not because of ML training (that&amp;rsquo;s Python&amp;rsquo;s domain), but because modern AI development is just HTTP calls, and everything around it is web engineering.&lt;/p&gt;&#xA;&lt;p&gt;The core argument: LLM integration is an HTTP call. What matters is everything around it — streaming responses, persisting conversations, tracking costs, switching providers. That&amp;rsquo;s where Rails shines.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buffered vs Unbuffered I/O on Unix</title>
      <link>https://viniciusrocha.com/posts/buffered-vs-unbuffered-i/o-on-unix/</link>
      <pubDate>Thu, 30 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/buffered-vs-unbuffered-i/o-on-unix/</guid>
      <description>&lt;div class=&#34;tldr-callout&#34;&gt;&#xA;  &lt;span class=&#34;tldr-label&#34;&gt;TL;DR&lt;/span&gt;&#xA;  &lt;div class=&#34;tldr-content&#34;&gt;&lt;ul&gt;&#xA;&lt;li&gt;Buffered I/O batches data in user-space (or library) buffers and performs fewer, larger system calls. Great for throughput.&lt;/li&gt;&#xA;&lt;li&gt;Unbuffered I/O sends data directly (or more directly) to the kernel/device, offering lower-latency and more predictable timing — at a throughput cost for many small ops.&lt;/li&gt;&#xA;&lt;li&gt;Use buffered I/O for normal file processing and high-throughput tasks. Use unbuffered or synchronous I/O when you need immediate visibility, determinism, or strict durability.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;what-buffered-and-unbuffered-mean&#34;&gt;What &amp;lsquo;buffered&amp;rsquo; and &amp;lsquo;unbuffered&amp;rsquo; mean&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Buffered I/O: The runtime (for example, the C standard library&amp;rsquo;s &lt;code&gt;FILE*&lt;/code&gt;) keeps an intermediate buffer and only calls &lt;code&gt;read()&lt;/code&gt;/&lt;code&gt;write()&lt;/code&gt; when the buffer is full, empty, or flushed. This reduces the number of system calls and generally improves throughput.&lt;/li&gt;&#xA;&lt;li&gt;Unbuffered I/O: Your operations are passed to the kernel (or device) with minimal user-space aggregation. Examples: calling POSIX &lt;code&gt;read()&lt;/code&gt;/&lt;code&gt;write()&lt;/code&gt; repeatedly with small sizes.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;two-layers-of-buffering-on-unix&#34;&gt;Two layers of buffering on Unix&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;User-space buffering (stdio, language runtime) — what most people mean by &amp;ldquo;buffered I/O&amp;rdquo; at the application level.&lt;/li&gt;&#xA;&lt;li&gt;Kernel page cache — even after &lt;code&gt;write()&lt;/code&gt; returns, the kernel often holds the content in RAM (the page cache) until it writes to disk. To make data durable to stable storage you need &lt;code&gt;fsync()&lt;/code&gt;/&lt;code&gt;fdatasync()&lt;/code&gt; or &lt;code&gt;O_SYNC&lt;/code&gt;/&lt;code&gt;O_DSYNC&lt;/code&gt; semantics.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Understanding both layers matters: you may &lt;code&gt;fflush()&lt;/code&gt; (user-space) and still need &lt;code&gt;fsync()&lt;/code&gt; (kernel/disk) if you require persistence.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix time values (the epoch)</title>
      <link>https://viniciusrocha.com/posts/unix-time-values-the-epoch/</link>
      <pubDate>Thu, 16 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/unix-time-values-the-epoch/</guid>
      <description>&lt;p&gt;Unix time (often called &amp;ldquo;the epoch&amp;rdquo;) is a simple way to represent a point in time: the number of seconds that have elapsed since 1970-01-01 00:00:00 UTC, not counting leap seconds. It&amp;rsquo;s compact, language-agnostic, and easy to compare and sort.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://imgs.xkcd.com/comics/bug.png&#34; alt=&#34;xkcd 376: Bug&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Comic: &lt;a href=&#34;https://xkcd.com/376/&#34;&gt;xkcd #376&lt;/a&gt; — used under the &lt;a href=&#34;https://creativecommons.org/licenses/by-nc/2.5/&#34;&gt;Creative Commons Attribution-NonCommercial 2.5 License&lt;/a&gt;. Credit: Randall Munroe / xkcd.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;tldr-callout&#34;&gt;&#xA;  &lt;span class=&#34;tldr-label&#34;&gt;TL;DR&lt;/span&gt;&#xA;  &lt;div class=&#34;tldr-content&#34;&gt;&lt;ul&gt;&#xA;&lt;li&gt;Unix time is seconds elapsed since 1970-01-01 00:00:00 UTC, typically stored as a 64-bit integer.&lt;/li&gt;&#xA;&lt;li&gt;Use it for internal storage, comparisons, rate limiting, TTLs, and compact binary formats.&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t use it for display, calendar/timezone logic, or precise elapsed intervals — use human-readable timestamps (ISO 8601) and monotonic clocks instead.&lt;/li&gt;&#xA;&lt;li&gt;Always use 64-bit integers; 32-bit overflows in 2038.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;quick-examples&#34;&gt;Quick examples&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Shell: &lt;code&gt;date +%s&lt;/code&gt; prints the current Unix time in seconds.&lt;/li&gt;&#xA;&lt;li&gt;Python: &lt;code&gt;import time; int(time.time())&lt;/code&gt; — seconds, or &lt;code&gt;time.time()&lt;/code&gt; for fractional seconds.&lt;/li&gt;&#xA;&lt;li&gt;JavaScript: &lt;code&gt;Math.floor(Date.now() / 1000)&lt;/code&gt; — Date.now() returns milliseconds.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;when-you-should-use-unix-time&#34;&gt;When you should use Unix time&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Machine-to-machine timestamps: compact, fast to compare, and well supported across platforms.&lt;/li&gt;&#xA;&lt;li&gt;Databases and indexes where you only need chronological ordering or durations.&lt;/li&gt;&#xA;&lt;li&gt;Protocols or binary formats that need a timezone-independent, compact numeric representation.&lt;/li&gt;&#xA;&lt;li&gt;Short-lived logging or metrics where space and parsing speed matter.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Practical rule: use Unix time for internal storage and calculations (sorting, rate limiting, TTLs), especially when you also store the timezone or a canonical representation elsewhere.&lt;/p&gt;</description>
    </item>
    <item>
      <title>tmux cheat sheet</title>
      <link>https://viniciusrocha.com/posts/tmux-cheat-sheet/</link>
      <pubDate>Wed, 05 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/tmux-cheat-sheet/</guid>
      <description>&lt;p&gt;This is a live document that I&amp;rsquo;m planning to maintain as I get more familiar with tmux.&lt;/p&gt;&#xA;&lt;h2 id=&#34;key-bindings&#34;&gt;Key bindings&lt;/h2&gt;&#xA;&lt;p&gt;All keybindings should be prefixed with a prefix key, &lt;code&gt;C-b&lt;/code&gt; (CTRL+b) by default, followed by a command key.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Category&lt;/th&gt;&#xA;          &lt;th&gt;Key binding&lt;/th&gt;&#xA;          &lt;th&gt;Description&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Window&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Create new window&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Window&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;,&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Rename window&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Window&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Choose window from list&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Window&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;0&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go from window 0 to 9&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Window&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to next window&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Split into two panes, left and right&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;&amp;quot;&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Split into two panes, top and bottom&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Left&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to left pane&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Right&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to right pane&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Down&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to pane at the bottom&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Up&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to pane at the top&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Go to next pane&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Close/kill current pane&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Pane&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;q&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Briefly display pane indexes.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;System&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;List all key bindings&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;System&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Detach&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;System&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;:&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Enter tmux command prompt&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;man 1 tmux&lt;/code&gt; (&lt;a href=&#34;https://man.openbsd.org/OpenBSD-current/man1/tmux.1&#34;&gt;web version&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://github.com/tmux/tmux/wiki&#34;&gt;GitHub.com/tmux/tmux&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;[video] &lt;a href=&#34;https://www.youtube.com/watch?v=niuOc02Rvrc&#34;&gt;Tmux will SKYROCKET your productivity - here&amp;rsquo;s how&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;[video] &lt;a href=&#34;https://www.youtube.com/watch?v=DzNmUNvnB04&#34;&gt;Tmux has forever changed the way I write code.&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Installing Ruby using chruby and ruby-install</title>
      <link>https://viniciusrocha.com/posts/installing-ruby-using-chruby-and-ruby-install/</link>
      <pubDate>Thu, 18 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/installing-ruby-using-chruby-and-ruby-install/</guid>
      <description>&lt;p&gt;Every Ruby developer will most likely be using a Ruby version manager. The most popular ones are: &lt;a href=&#34;https://rvm.io&#34;&gt;RVM&lt;/a&gt;, &lt;a href=&#34;https://github.com/rbenv/rbenv&#34;&gt;rbenv&lt;/a&gt;, and &lt;a href=&#34;https://github.com/postmodern/chruby&#34;&gt;chruby&lt;/a&gt;. You can use whatever makes you happy. I went with &lt;code&gt;chruby&lt;/code&gt;, and I&amp;rsquo;m happy with it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-chruby&#34;&gt;What is chruby&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;chruby&lt;/code&gt; is a command line tool that lets you switch between different versions of Ruby. It allows you to change between them manually, or it can change the version for you automatically, as you navigate between project folders.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Setup Rails using chruby and ruby-install</title>
      <link>https://viniciusrocha.com/posts/setup-rails-using-chruby-and-ruby-install/</link>
      <pubDate>Wed, 15 Dec 2021 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/setup-rails-using-chruby-and-ruby-install/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Check the updated version of this post: &lt;a href=&#34;https://viniciusrocha.com/posts/installing-ruby-using-chruby/&#34;&gt;Installing Ruby using chruby and ruby-install&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;Here are the steps to install and set up Ruby and Ruby on Rails on macOS using &lt;a href=&#34;https://github.com/postmodern/chruby&#34;&gt;chruby&lt;/a&gt; and &lt;a href=&#34;https://github.com/postmodern/ruby-install&#34;&gt;ruby-install&lt;/a&gt;. Both are very light tools written by &lt;a href=&#34;https://postmodern.github.io/&#34;&gt;Hal Brodigan&lt;/a&gt;. A similar approach can also be used on Linux or Windows/WSL.&lt;/p&gt;&#xA;&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s start by installing &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt;. Follow the official installation instructions on their website.&lt;/p&gt;&#xA;&lt;p&gt;With that in place, we can now get &lt;code&gt;chruby&lt;/code&gt; and &lt;code&gt;ruby-install&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Z shell</title>
      <link>https://viniciusrocha.com/posts/the-z-shell/</link>
      <pubDate>Tue, 03 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/the-z-shell/</guid>
      <description>&lt;h2 id=&#34;what-it-is&#34;&gt;What it is&lt;/h2&gt;&#xA;&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Shell_(computing)&#34;&gt;shell&lt;/a&gt; is what sits between the user and the core of the operating system, usually in a form of a command line interface (CLI). The most popular shell on Linux distributions is &lt;a href=&#34;https://en.wikipedia.org/wiki/Bash_(Unix_shell)&#34;&gt;bash&lt;/a&gt;. In 2019, Apple started releasing the MacOS with &lt;a href=&#34;https://en.wikipedia.org/wiki/Z_shell&#34;&gt;Zsh (Z shell)&lt;/a&gt; by default. I believe that is one the reasons that made zsh so popular.&lt;/p&gt;&#xA;&lt;h2 id=&#34;installing-it-on-ubuntu&#34;&gt;Installing it on Ubuntu&lt;/h2&gt;&#xA;&lt;p&gt;Ubuntu, one of the most popular Linux distributions, comes with bash pre-installed. To install Zsh on it, just run the following commands:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Add a JSON configuration file to a .NET Core console application</title>
      <link>https://viniciusrocha.com/posts/add-a-json-configuration-file-to-a-.net-core-console-application/</link>
      <pubDate>Tue, 02 Mar 2021 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/add-a-json-configuration-file-to-a-.net-core-console-application/</guid>
      <description>&lt;p&gt;A .NET Core application can handle configuration using different formats (providers) like memory, command line and environment. Here, we will be using a file provider, more specifically, a &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.json.jsonconfigurationprovider&#34;&gt;JsonConfigurationProvider&lt;/a&gt;. &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/core/extensions/configuration-providers&#34;&gt;Click on this link&lt;/a&gt; to learn more about the different types of configuration providers.&lt;/p&gt;&#xA;&lt;h2 id=&#34;project-setup&#34;&gt;Project Setup&lt;/h2&gt;&#xA;&lt;p&gt;We will start by creating a console application and adding the &lt;a href=&#34;https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Json/&#34;&gt;NuGet package&lt;/a&gt; for the provider. In our case, it will be a JSON provider.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dotnet new console -o sample-configuration -n SampleConfiguration&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; SampleConfiguration&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dotnet add package Microsoft.Extensions.Configuration.Json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s also add an &lt;code&gt;appsettings.json&lt;/code&gt; file that we can use for testing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Handling WPF Window Dialog events, the elegant way</title>
      <link>https://viniciusrocha.com/posts/handling-wpf-window-dialog-events-the-elegant-way/</link>
      <pubDate>Fri, 26 Jul 2019 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/handling-wpf-window-dialog-events-the-elegant-way/</guid>
      <description>&lt;p&gt;Here are two elegant ways that you can use to handle WPF Dialogs from the ViewModel. I will demonstrate both examples by closing a WPF Window Dialog from the ViewModel depending on some logic.&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-events&#34;&gt;Using Events&lt;/h2&gt;&#xA;&lt;p&gt;The first solution is by using an event that notifies the window dialog to close. Consider the following example:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cs&#34; data-lang=&#34;cs&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;DialogViewModel&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;event&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventHandler&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Saved&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DialogViewModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;SaveCommand&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DelegateCommand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OnSave&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ICommand&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SaveCommand&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// SOME LOGIC TO SAVE GOES HERE&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;//&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Saved&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Invoke&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventArgs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The dialog window can listen to that event and close itself accordingly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ASP.NET Conditional Validation</title>
      <link>https://viniciusrocha.com/posts/asp.net-conditional-validation/</link>
      <pubDate>Wed, 20 Sep 2017 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/asp.net-conditional-validation/</guid>
      <description>&lt;p&gt;Conditional validation can be very useful, and I&amp;rsquo;m glad that I found an elegant way of doing it. You can use the same View-Model on two different actions of your controller and have different validations for each of them.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sample-scenario&#34;&gt;Sample Scenario&lt;/h2&gt;&#xA;&lt;p&gt;To help illustrate the issue and the solution, let&amp;rsquo;s describe a simple scenario for user management. We will have a controller that adds and edits users. I will abstract the business layer so we can focus only on the user validation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unit Testing NHibernate Mappings</title>
      <link>https://viniciusrocha.com/posts/unit-testing-nhibernate-mappings/</link>
      <pubDate>Wed, 21 Jun 2017 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/posts/unit-testing-nhibernate-mappings/</guid>
      <description>&lt;p&gt;What is the best approach to map your domain classes to the database using NHibernate? After doing some tests, I believe that the best answer is: it doesn&amp;rsquo;t matter. As long as you have unit tests in place for it, you are covered.&lt;/p&gt;&#xA;&lt;p&gt;The same mapping issue that you will face using &lt;a href=&#34;http://nhibernate.info/doc/nhibernate-reference/mapping.html&#34;&gt;HBM files&lt;/a&gt;, you will encounter using &lt;a href=&#34;http://www.fluentnhibernate.org/&#34;&gt;FHN&lt;/a&gt; or &lt;a href=&#34;http://notherdev.blogspot.ca/2012/02/nhibernates-mapping-by-code-summary.html&#34;&gt;Mapping By Code&lt;/a&gt;. Because of that, I did some experiments on what would be a good approach to unit test NHibernate mappings.&lt;/p&gt;</description>
    </item>
    <item>
      <title>About</title>
      <link>https://viniciusrocha.com/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/about/</guid>
      <description>&lt;p&gt;Hey, I&amp;rsquo;m Vinicius Rocha — a software developer based in the United States, originally from Brazil.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been writing code for over two decades now. Started back in the early .NET days and have been going ever since, picking up new things along the way. I mostly work on backend stuff, but I&amp;rsquo;ve always been into the whole picture — tooling, infrastructure, the little things that make day-to-day dev life less painful.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Archives</title>
      <link>https://viniciusrocha.com/archives/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/archives/</guid>
      <description></description>
    </item>
    <item>
      <title>Quotes</title>
      <link>https://viniciusrocha.com/quotes/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://viniciusrocha.com/quotes/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Simplicity is prerequisite for reliability.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Edsger W. Dijkstra&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Make it work, make it right, make it fast.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Kent Beck&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Talk is cheap. Show me the code.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Linus Torvalds&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Premature optimization is the root of all evil.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Donald Knuth&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;The best way to predict the future is to invent it.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Alan Kay&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Good code is its own best documentation.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;— Steve McConnell&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
