<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Yuvaraj's Blog]]></title><description><![CDATA[Yuvaraj's Blog]]></description><link>https://blog.jyuvaraj.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1650392688302/m_WayE7Vj.png</url><title>Yuvaraj&apos;s Blog</title><link>https://blog.jyuvaraj.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 10:53:42 GMT</lastBuildDate><atom:link href="https://blog.jyuvaraj.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Monitoring Ruby Process Memory Without the Bloat: A Lightweight DIY Approach]]></title><description><![CDATA[The Problem: When Heavyweight Tools Are Too Heavy
Recently, I found myself needing to monitor memory usage in a long-running Ruby process. Like any good developer, I first reached for popular tools like memory_profiler and get_process_mem. But there ...]]></description><link>https://blog.jyuvaraj.com/monitoring-ruby-process-memory-without-the-bloat-a-lightweight-diy-approach</link><guid isPermaLink="true">https://blog.jyuvaraj.com/monitoring-ruby-process-memory-without-the-bloat-a-lightweight-diy-approach</guid><category><![CDATA[Ruby]]></category><category><![CDATA[Rails]]></category><category><![CDATA[memory-management]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Sat, 25 Jan 2025 18:30:00 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-the-problem-when-heavyweight-tools-are-too-heavy"><strong>The Problem: When Heavyweight Tools Are Too Heavy</strong></h2>
<p>Recently, I found myself needing to monitor memory usage in a long-running Ruby process. Like any good developer, I first reached for popular tools like <code>memory_profiler</code> and <code>get_process_mem</code>. But there was a problem: these tools themselves consumed significant memory, which felt ironic when trying to monitor a memory-sensitive process.</p>
<p>I realized I didn't need detailed object allocation traces or complex statistics – I just wanted a simple answer: <em>"How much memory is my process using right now?"</em></p>
<h2 id="heading-the-discovery-linuxs-proc-filesystem"><strong>The Discovery: Linux's Proc Filesystem</strong></h2>
<p>The solution came from Linux's <code>/proc</code> filesystem, specifically <code>/proc/self/statm</code>. This special file contains memory usage information for the current process in a simple space-separated format.</p>
<p>Key fields:</p>
<ul>
<li><p><strong>Field 1:</strong> Total program size (virtual memory)</p>
</li>
<li><p><strong>Field 2:</strong> Resident Set Size (RSS) - physical memory being used</p>
</li>
<li><p><strong>Field 3:</strong> Shared pages</p>
</li>
</ul>
<p>Since we care about actual physical memory usage, RSS (field 2) is our golden number.</p>
<h2 id="heading-the-solution-a-minimal-memory-logger"><strong>The Solution: A Minimal Memory Logger</strong></h2>
<p>Here's the core implementation I landed on:</p>
<pre><code class="lang-ruby"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">log_memory_usage</span><span class="hljs-params">(<span class="hljs-symbol">interval:</span> <span class="hljs-number">5</span>, <span class="hljs-symbol">log_path:</span> <span class="hljs-string">"memory.log"</span>)</span></span>
  Thread.new <span class="hljs-keyword">do</span>
    loop <span class="hljs-keyword">do</span>
      <span class="hljs-keyword">begin</span>
        <span class="hljs-comment"># Get RSS from proc in pages (1 page = 4KB)</span>
        rss_pages = File.read(<span class="hljs-string">'/proc/self/statm'</span>).split[<span class="hljs-number">1</span>].to_i
        rss_kb = rss_pages * <span class="hljs-number">4</span>

        <span class="hljs-comment"># Append to log file with timestamp</span>
        File.open(log_path, <span class="hljs-string">'a'</span>) <span class="hljs-keyword">do</span> <span class="hljs-params">|f|</span>
          f.puts(<span class="hljs-string">"[<span class="hljs-subst">#{Time.now.utc.iso8601}</span>] Memory: <span class="hljs-subst">#{rss_kb}</span> KB"</span>)
          f.flush
        <span class="hljs-keyword">end</span>
      <span class="hljs-keyword">rescue</span> =&gt; e
        $stderr.puts <span class="hljs-string">"Memory logging failed: <span class="hljs-subst">#{e}</span>"</span>
      <span class="hljs-keyword">end</span>

      sleep(interval)
    <span class="hljs-keyword">end</span>
  <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p><strong>Why This Works:</strong></p>
<ol>
<li><p><strong>Lightweight:</strong> Adds negligible overhead compared to gems like <code>memory_profiler</code></p>
</li>
<li><p><strong>Simple:</strong> Just a few lines of core logic</p>
</li>
<li><p><strong>Efficient:</strong> File.flush ensures writes survive process crashes</p>
</li>
<li><p><strong>Thread-safe:</strong> Runs in background without blocking main process</p>
</li>
</ol>
<hr />
<h2 id="heading-key-benefits-i-discovered"><strong>Key Benefits I Discovered</strong></h2>
<ol>
<li><p><strong>Zero Dependencies</strong><br /> No need to add gems to your Gemfile or worry about version conflicts</p>
</li>
<li><p><strong>Customizable Logging</strong><br /> Easily adjust:</p>
<ul>
<li><p>Log frequency (from seconds to hours)</p>
</li>
<li><p>Output format (JSON, CSV, etc.)</p>
</li>
<li><p>Destination (file, STDOUT, remote service)</p>
</li>
</ul>
</li>
<li><p><strong>Low Maintenance</strong><br /> The <code>/proc</code> interface has been stable for decades – unlikely to break</p>
</li>
<li><p><strong>Surprisingly Portable</strong><br /> Works on:</p>
<ul>
<li><p>Any Linux distribution</p>
</li>
<li><p>Docker containers</p>
</li>
<li><p>WSL (Windows Subsystem for Linux)</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-caveats-and-alternatives"><strong>Caveats and Alternatives</strong></h2>
<ol>
<li><strong>Linux-only</strong><br /> For macOS, consider using <code>ps</code> command parsing:</li>
</ol>
<pre><code class="lang-bash">rss_kb = `ps -o rss= -p <span class="hljs-comment">#{Process.pid}`.to_i</span>
</code></pre>
<ol start="2">
<li><p><strong>Not for Detailed Profiling</strong><br /> Use <code>memory_profiler</code> if you need object-level granularity</p>
</li>
<li><p><strong>Container-Aware</strong><br /> In Docker, remember this shows container memory, not host memory</p>
</li>
</ol>
<h2 id="heading-the-surprising-lesson"><strong>The Surprising Lesson</strong></h2>
<p>Sometimes the simplest solutions are the best. While sophisticated tools have their place, there's value in understanding your platform's fundamentals. By leveraging Linux's built-in instrumentation, I achieved:</p>
<ul>
<li><p>Negligible memory footprint compared to gem-based solutions</p>
</li>
<li><p>Custom logging perfectly tailored to my needs</p>
</li>
<li><p>Deeper understanding of process memory management</p>
</li>
</ul>
<h2 id="heading-try-it-yourself"><strong>Try It Yourself!</strong></h2>
<p>Next time you need basic memory monitoring, consider this approach. You might be surprised how much you can achieve with:</p>
<ul>
<li><p>A few lines of Ruby</p>
</li>
<li><p>Linux fundamentals</p>
</li>
<li><p>A curious mindset</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Unlocking Productivity: My Notes on Cal Newport’s Deep Work]]></title><description><![CDATA[If you’re like me, you’ve probably struggled to concentrate in an era where distractions are just a click away. Emails, social media, and endless meetings often leave us feeling busy but unproductive. That’s why Cal Newport’s Deep Work resonated with...]]></description><link>https://blog.jyuvaraj.com/unlocking-productivity-my-notes-on-cal-newports-deep-work</link><guid isPermaLink="true">https://blog.jyuvaraj.com/unlocking-productivity-my-notes-on-cal-newports-deep-work</guid><category><![CDATA[Productivity]]></category><category><![CDATA[Time management]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Fri, 27 Dec 2024 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p>If you’re like me, you’ve probably struggled to concentrate in an era where distractions are just a click away. Emails, social media, and endless meetings often leave us feeling busy but unproductive. That’s why Cal Newport’s <a target="_blank" href="https://www.goodreads.com/book/show/25744928-deep-work"><em>Deep Work</em></a> resonated with me—it’s a blueprint for cutting through the noise to achieve meaningful results. Below, I’ve distilled the book’s core ideas into actionable insights that transformed how I work.</p>
<h2 id="heading-why-deep-work-matters"><strong>Why Deep Work Matters</strong></h2>
<p>Newport defines <em>deep work</em> as the ability to focus without distraction on cognitively demanding tasks. It’s a skill that’s becoming rare—and increasingly valuable—in our hyperconnected world. Here’s how to master it.</p>
<h2 id="heading-rule-1-work-deeply"><strong>Rule #1: Work Deeply</strong></h2>
<h3 id="heading-choose-your-deep-work-philosophy"><strong>Choose Your Deep Work Philosophy</strong></h3>
<p>Not everyone can (or should) become a hermit. Newport outlines four approaches:</p>
<ol>
<li><p><strong>Monastic</strong>: Eliminate shallow work entirely (ideal for solo creators).</p>
</li>
<li><p><strong>Bimodal</strong>: Alternate between deep work sprints and shallow periods (e.g., dedicate 2 days/week to focus).</p>
</li>
<li><p><strong>Rhythmic</strong>: Build a daily habit (e.g., 90-minute morning blocks).</p>
</li>
<li><p><strong>Journalistic</strong>: Sneak in deep work whenever possible (for unpredictable schedules).</p>
</li>
</ol>
<h3 id="heading-ritualize-your-focus"><strong>Ritualize Your Focus</strong></h3>
<p>Newport emphasizes creating a routine to signal your brain it’s time to dive deep. Ask:</p>
<ul>
<li><p><strong>Where and for how long</strong> will you work?</p>
</li>
<li><p><strong>How</strong> will you avoid distractions? (e.g., phone on airplane mode).</p>
</li>
<li><p><strong>How</strong> will you prepare? (e.g., water, pre-planned tasks).</p>
</li>
</ul>
<h3 id="heading-the-power-of-grand-gestures"><strong>The Power of Grand Gestures</strong></h3>
<p>Sometimes, you need a bold move to kickstart focus. J.K. Rowling checked into a hotel to finish <em>Harry Potter</em>. For us mortals, locking your door or working from a café can create a similar “focus zone.”</p>
<h3 id="heading-execute-like-a-business"><strong>Execute Like a Business</strong></h3>
<p>Use the <strong>4 Disciplines of Execution (4DX)</strong>:</p>
<ol>
<li><p><strong>Wildly Important Goals</strong>: Define <em>one</em> clear objective (e.g., “Build app MVP in 6 weeks”).</p>
</li>
<li><p><strong>Lead Measures</strong>: Track input metrics (e.g., hours spent in deep work).</p>
</li>
<li><p><strong>Scoreboard</strong>: Visually track progress (I use a whiteboard).</p>
</li>
<li><p><strong>Weekly Reviews</strong>: Adjust strategies based on what’s working.</p>
</li>
</ol>
<h2 id="heading-rule-2-embrace-boredom"><strong>Rule #2: Embrace Boredom</strong></h2>
<p>Concentration is like a muscle—it needs training.</p>
<h3 id="heading-schedule-distraction-not-focus"><strong>Schedule Distraction, Not Focus</strong></h3>
<p>Instead of resisting distractions, <em>schedule</em> them. For example:</p>
<ul>
<li><p>Check emails/Slack only at two dedicated times like 11 AM and 4 PM.</p>
</li>
<li><p>Use a notepad to jot down non-urgent tasks instead of impulsively switching tabs.</p>
</li>
</ul>
<h3 id="heading-work-like-teddy-roosevelt"><strong>Work Like Teddy Roosevelt</strong></h3>
<p>The former U.S. president mastered intense bursts of focus. Try this:</p>
<ul>
<li><p>Pick a task, set a deadline <em>half</em> your usual time, and work relentlessly until done.</p>
</li>
<li><p>Limit this to once a week to avoid burnout.</p>
</li>
</ul>
<h2 id="heading-rule-3-quit-social-media"><strong>Rule #3: Quit Social Media</strong></h2>
<p>Newport isn’t anti-tech—he’s pro-intentionality. For a more detailed read on this, checkout his other book <a target="_blank" href="https://www.goodreads.com/book/show/40672036-digital-minimalism">Digital Minimalism</a></p>
<h3 id="heading-the-30-day-social-media-detox"><strong>The 30-Day Social Media Detox</strong></h3>
<ol>
<li><p>Quit all non-essential apps for 30 days.</p>
</li>
<li><p>Afterward, ask: <em>Did I miss it? Did others care?</em></p>
</li>
<li><p>If “no” to both, delete it permanently.</p>
</li>
</ol>
<h2 id="heading-rule-4-drain-the-shallows"><strong>Rule #4: Drain the Shallows</strong></h2>
<p>Shallow work (emails, meetings) is inevitable, but minimize it.</p>
<h3 id="heading-schedule-every-minute"><strong>Schedule Every Minute</strong></h3>
<p>Plan your day in 30-minute blocks. Include breaks! When interruptions happen, <em>revise your schedule</em> instead of abandoning it.</p>
<p><strong>My Routine</strong>: I use Google Calendar color-coded blocks. Over time, I’ve reduced shallow work from 6 to 3 hours/day.</p>
<h3 id="heading-become-hard-to-reach"><strong>Become Hard to Reach</strong></h3>
<ul>
<li><p>Set email filters.</p>
</li>
<li><p>Use autoresponders to manage expectations.</p>
</li>
<li><p>Say “no” to non-critical requests.</p>
</li>
</ul>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p><em>Deep Work</em> isn’t about working harder—it’s about working smarter. By adopting even a few of these strategies, I’ve reclaimed hours in my day and produced higher-quality work. While these notes capture the essence, I highly recommend reading the book for deeper insights.</p>
<p><em>This post is based on my personal notes and takeaways from Cal Newport’s Deep Work. All credit goes to the author for these transformative ideas.</em></p>
]]></content:encoded></item><item><title><![CDATA[Never Fix a "Performance" Issue Without Measuring It]]></title><description><![CDATA[As a software engineer specializing in performance optimization, I’ve lost count of how many times I’ve seen well-intentioned developers "fix" a problem that wasn’t actually a problem. In Ruby on Rails codebases—and indeed, in any software ecosystem—...]]></description><link>https://blog.jyuvaraj.com/never-fix-a-performance-issue-without-measuring-it</link><guid isPermaLink="true">https://blog.jyuvaraj.com/never-fix-a-performance-issue-without-measuring-it</guid><category><![CDATA[performance]]></category><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Fri, 08 Nov 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/vVHXeu0YNbk/upload/c3e461c1a3a093ebb718b3d0d3e0e514.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a software engineer specializing in performance optimization, I’ve lost count of how many times I’ve seen well-intentioned developers "fix" a problem that wasn’t actually a problem. In Ruby on Rails codebases—and indeed, in any software ecosystem—this happens alarmingly often. Developers refactor code for "speed," tweak database queries "to reduce latency," or obsess over micro-optimizations, all without ever measuring the actual impact of their changes. The result? Wasted time, unnecessary complexity, and sometimes even <em>slower</em> performance.</p>
<p>Let’s talk about why measurement is non-negotiable—and how skipping this step is like prescribing medicine without diagnosing the illness.</p>
<h2 id="heading-the-pitfalls-of-optimizing-blindly">The Pitfalls of Optimizing Blindly</h2>
<h3 id="heading-1-youre-probably-wrong-about-the-bottleneck">1. <strong>You’re Probably Wrong About the Bottleneck</strong></h3>
<p>Human intuition about performance is notoriously unreliable. What <em>feels</em> slow—say, a loop iterating over an array—might not be the culprit at all. In Rails, common performance pitfalls often lie in layers developers don’t directly interact with: inefficient database queries (N+1 issues), memory bloat, poorly configured caching, or even garbage collection overhead. Without profiling, you’re playing a guessing game.</p>
<h3 id="heading-2-you-risk-solving-the-wrong-problem">2. <strong>You Risk Solving the Wrong Problem</strong></h3>
<p>I once saw a team spend days rewriting a module to reduce its time complexity only to realize its execution was finishing in milliseconds in the first place. The real performance issue was a heavy IO operation down the line. By not measuring, they solved a problem that didn’t matter—and ignored the one that did.</p>
<h3 id="heading-3-you-might-make-things-worse">3. <strong>You Might Make Things Worse</strong></h3>
<p>Premature optimizations can introduce subtle bugs, reduce code readability, or even degrade performance. For example, adding aggressive caching without understanding the data access patterns might lead to stale data or increased memory pressure.</p>
<h2 id="heading-the-rails-tools-you-should-be-using">The Rails Tools You Should Be Using</h2>
<p>Ruby on Rails provides a robust toolkit for measuring performance. Here’s where to start:</p>
<h3 id="heading-1-profiling-tools">1. <strong>Profiling Tools</strong></h3>
<ul>
<li><p><strong>rack-mini-profiler</strong>: A gem that displays performance diagnostics directly in your browser. It highlights slow database queries, render times, and more.</p>
</li>
<li><p><strong>ruby-prof</strong>: For deep method-level profiling. These tools help identify CPU bottlenecks.</p>
</li>
<li><p><strong>bullet</strong>: Catches N+1 query issues before they become problems.</p>
</li>
<li><p><strong>memory_profiler:</strong> For analyzing where memory is being allocated.</p>
</li>
</ul>
<h3 id="heading-2-benchmarking">2. <strong>Benchmarking</strong></h3>
<p>Use Ruby’s <code>Benchmark</code> module or the <code>benchmark-ips</code> gem to measure code execution time. For example:</p>
<pre><code class="lang-ruby">Benchmark.ips <span class="hljs-keyword">do</span> <span class="hljs-params">|x|</span>
  x.report(<span class="hljs-string">"original"</span>) { SomeModel.expensive_method }
  x.report(<span class="hljs-string">"optimized"</span>) { SomeModel.optimized_expensive_method }
  x.compare!
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-3-database-query-analysis">3. <strong>Database Query Analysis</strong></h3>
<p>Check your Rails server logs for slow queries, or use your database’s slow query logs to identify high-cost SQL statements. Tools like <code>explain</code> can reveal missing indexes or inefficient query plans.</p>
<h2 id="heading-a-practical-workflow-for-performance-fixes">A Practical Workflow for Performance Fixes</h2>
<ol>
<li><p><strong>Reproduce the Issue</strong><br /> Can you reliably trigger the slowdown? If not, you’re not ready to fix it.</p>
</li>
<li><p><strong>Establish a Baseline</strong><br /> Measure the current performance. For example: “This CSV processor takes 10 seconds to process 100k lines”</p>
</li>
<li><p><strong>Profile, Don’t Assume</strong><br /> Run profiling tools to identify the root cause. Is it CPU-bound Ruby code? Database latency? Garbage collection? Network calls?</p>
</li>
<li><p><strong>Target the Bottleneck</strong><br /> Focus your efforts on the slowest part of the system. If a database query takes 80% of the request time, optimizing Ruby code won’t help.</p>
</li>
<li><p><strong>Validate the Fix</strong><br /> Re-measure after your changes. Did the bottleneck improve? Did you inadvertently shift the bottleneck elsewhere?</p>
</li>
</ol>
<h2 id="heading-a-rails-specific-example-the-n1-trap">A Rails-Specific Example: The N+1 Trap</h2>
<p>Imagine a view rendering a list of <code>User</code> records, each with an <code>address</code>. A developer notices the page is slow and assumes the issue is rendering speed. They "optimize" by preloading data:</p>
<pre><code class="lang-ruby"><span class="hljs-comment"># Before (triggers N+1 queries)</span>
@users = User.all
</code></pre>
<pre><code class="lang-ruby"><span class="hljs-comment"># After (fixes N+1 but adds unnecessary overhead)</span>
@users = User.includes(<span class="hljs-symbol">:address</span>, <span class="hljs-symbol">:profile</span>, <span class="hljs-symbol">:orders</span>, <span class="hljs-symbol">:preferences</span>).all
</code></pre>
<p>But without measuring, they might over-include associations, bloating memory and query time. A better approach:</p>
<ol>
<li><p>Use <code>rack-mini-profiler</code> or <code>bullet</code> to confirm N+1 queries.</p>
</li>
<li><p>Measure the query time with and without <code>includes</code>.</p>
</li>
<li><p>Use <code>includes</code> selectively: <code>User.includes(:address)</code> if addresses are the only association needed.</p>
</li>
</ol>
<h2 id="heading-when-not-to-optimize">When <em>Not</em> to Optimize</h2>
<p>Not every slow line of code needs fixing. Ask:</p>
<ul>
<li><p>Does this impact user experience or business goals?</p>
</li>
<li><p>Is the code on a hot path (e.g., called thousands of times per minute)?</p>
</li>
<li><p>Is the current performance "good enough" for the use case?</p>
</li>
</ul>
<p>If a method runs once a day and takes 2 seconds, your time is better spent elsewhere.</p>
<h2 id="heading-the-bottom-line">The Bottom Line</h2>
<p>Performance work is science, not art. Guessing wastes time; measuring saves it. In Rails, where layers like ActiveRecord abstractions and middleware can obscure bottlenecks, profiling is your flashlight in the dark. Before you refactor, cache, or rewrite, ask: <em>What does the data say?</em></p>
<p>Your future self—and your team—will thank you.</p>
]]></content:encoded></item><item><title><![CDATA[More people should use `less`]]></title><description><![CDATA[In the world of Linux command-line tools, there’s an old joke: “Why should more people use less? Because less is more!” This pun isn’t just a play on words—it’s a nod to one of the most underrated utilities in a sysadmin or developer’s toolkit. While...]]></description><link>https://blog.jyuvaraj.com/more-people-should-use-less</link><guid isPermaLink="true">https://blog.jyuvaraj.com/more-people-should-use-less</guid><category><![CDATA[Linux]]></category><category><![CDATA[linux for beginners]]></category><category><![CDATA[linux-commands]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Fri, 25 Oct 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/fti002hQCCA/upload/49df5a654bc710744a6e88e1d662bb22.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of Linux command-line tools, there’s an old joke: “Why should more people use <code>less</code>? Because <code>less</code> is more!” This pun isn’t just a play on words—it’s a nod to one of the most underrated utilities in a sysadmin or developer’s toolkit. While many users default to commands like <code>cat</code> or <code>more</code> to view files, the humble <code>less</code> command offers a superior experience for reading, navigating, and analyzing text. Let’s dive into why <code>less</code> deserves a prime spot in your workflow.</p>
<h2 id="heading-what-is-less">What is <code>less</code>?</h2>
<p><code>less</code> is a terminal pager designed to view and navigate through files or command output efficiently. Introduced in 1984 as a successor to <code>more</code>, it earned its name because it does “more” by requiring “less” effort (and because, unlike <code>more</code>, it allows backward movement in files). While <code>more</code> was limited to forward-only scrolling, <code>less</code> broke boundaries by enabling bidirectional navigation, robust searching, and seamless handling of massive files.</p>
<h2 id="heading-key-features-of-less">Key features of <code>less</code></h2>
<ol>
<li><p><strong>Scroll Freely, Forward <em>and</em> Backward</strong><br /> With <code>less</code>, you’re not stuck moving in one direction. Use the arrow keys (or vim motion keys if you prefer), <code>Page Up</code>/<code>Page Down</code> (or <code>f</code> and <code>b</code> like vim again), or even the spacebar to scroll. Want to jump to the end? Press <code>G</code>. Return to the top? Press <code>g</code>.</p>
</li>
<li><p><strong>Search Like a Pro</strong><br /> Tap <code>/</code> to start a forward search or <code>?</code> for a backward search. <code>less</code> highlights matches and lets you cycle through them with <code>n</code> (next match) or <code>N</code> (previous match).</p>
</li>
<li><p><strong>Handle Massive Files with Ease</strong><br /> Unlike text editors that load entire files into memory, <code>less</code> opens files incrementally. This makes it perfect for log files that are gigabytes in size—no freezing or lag.</p>
</li>
<li><p><strong>Follow Real-Time Updates</strong><br /> Watching a growing log file? Press <code>F</code> to enter “follow mode,” and <code>less</code> will tail the file in real time, similar to <code>tail -f</code>. Exit follow mode with <code>Ctrl+C</code>.</p>
</li>
<li><p><strong>Line Numbers and Wrapping</strong><br /> Toggle line numbers with <code>-N</code> (e.g., <code>less -N file.txt</code> or type <code>-N</code> after opening the file) or disable line wrapping with <code>-S</code> to avoid messy output.</p>
</li>
<li><p><strong>Show colors from your logs</strong></p>
<p> If you open a file with colored strings, then you can show those colors using the <code>-R</code> option.</p>
</li>
<li><p><strong>Integrate with Pipelines</strong><br /> Pipe output from commands like <code>grep</code>, <code>awk</code>, or <code>journalctl</code> directly into <code>less</code> for easier analysis:</p>
<pre><code class="lang-bash"> grep <span class="hljs-string">"ERROR"</span> app.log | less
</code></pre>
</li>
</ol>
<h2 id="heading-why-ditch-more-for-less">Why ditch <code>more</code> for <code>less</code>?</h2>
<p>The original <code>more</code> command is still around, but it lacks many of <code>less</code>’s features. For example:</p>
<ul>
<li><p><strong>No backward scrolling</strong>: Once you scroll past a page in <code>more</code>, you can’t go back.</p>
</li>
<li><p><strong>Limited navigation</strong>: <code>more</code> lacks search highlights, jump-to-end shortcuts, or follow mode.</p>
</li>
<li><p><strong>Basic functionality</strong>: It’s just… less.</p>
</li>
</ul>
<p>Even the manual page for <code>more</code> admits its shortcomings, often stating, “<code>more</code> has fewer features than <code>less</code>.”</p>
<h2 id="heading-getting-started-with-less">Getting started with <code>less</code></h2>
<p>Most Linux and macOS systems include <code>less</code> by default.</p>
<p>But, in case you don’t have it readily installed it is usually available in your OS’s package manager. In Ubuntu, you can run this to install less</p>
<pre><code class="lang-bash">sudo apt install less
</code></pre>
<p>To open a file:</p>
<pre><code class="lang-bash">less filename.txt
</code></pre>
<p><strong>Essential Commands:</strong></p>
<ul>
<li><p><code>q</code>: Quit.</p>
</li>
<li><p><code>/pattern</code>: Search for “pattern.”</p>
</li>
<li><p><code>:n</code> and <code>:p</code>: Navigate between multiple files (if opened with <code>less file1 file2</code>).</p>
</li>
<li><p><code>-i</code>: Ignore case in searches (use <code>less -i file</code>).</p>
</li>
<li><p><code>v</code>: Open the file in your default text editor (e.g., Vim).</p>
</li>
</ul>
<h2 id="heading-advanced-tips">Advanced tips</h2>
<ul>
<li><p><strong>View Compressed Files</strong><br />  Use <code>less</code> with tools like <code>zless</code> to view compressed files without manual extraction.</p>
</li>
<li><p><strong>Customize Display</strong><br />  Set environment variables in your shell config (e.g., <code>~/.bashrc</code>) to tweak <code>less</code>’s behavior. For example:</p>
<pre><code class="lang-bash">  <span class="hljs-built_in">export</span> LESS=<span class="hljs-string">"-i -N -S -R"</span>
</code></pre>
<p>  This ignores case in searches, enables line numbers, chops long lines, and shows colors.</p>
</li>
<li><p><strong>Avoid Binary Files</strong><br />  If you accidentally open a binary, <code>less</code> will warn you. Press <code>q</code> to exit, then use tools like <code>strings</code> or <code>xxd</code> instead.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In an era of bloated GUIs, <code>less</code> remains a lightweight, powerful tool for anyone working in the terminal. Its versatility, speed, and intuitive navigation make it indispensable for debugging logs, reading documentation, or exploring data. So next time you reflexively type <code>cat</code> or <code>more</code>, give <code>less</code> a try. After all, why settle for “more” when you can have… <em>less</em>?</p>
<p><strong>Pro Tip:</strong> Type <code>man less</code> to view its manual—ironically, you’ll be reading it <em>in</em> <code>less</code> itself. Now that’s meta!</p>
]]></content:encoded></item><item><title><![CDATA[How Not to Center a Div: A Masterclass in CSS Frustration]]></title><description><![CDATA[Ah yes, centering a div. The ancient quest that has brought seasoned developers to their knees and reduced interns to tears. While some might call it a "basic" CSS task, true legends know it’s actually a dark ritual requiring blood, sweat, and a sacr...]]></description><link>https://blog.jyuvaraj.com/how-not-to-center-a-div-a-masterclass-in-css-frustration</link><guid isPermaLink="true">https://blog.jyuvaraj.com/how-not-to-center-a-div-a-masterclass-in-css-frustration</guid><category><![CDATA[CSS]]></category><category><![CDATA[HTML5]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Sat, 17 Aug 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/WahfNoqbYnM/upload/ef5b886520a28c76419dbe01b2a467ee.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ah yes, centering a <code>div</code>. The ancient quest that has brought seasoned developers to their knees and reduced interns to tears. While some might call it a "basic" CSS task, true legends know it’s actually a dark ritual requiring blood, sweat, and a sacrificial offering to the Browser Gods. But fear not! Today, we’ll explore the <em>worst</em> ways to tackle this Herculean task.</p>
<h2 id="heading-1-throw-every-css-property-you-know-at-it"><strong>1. Throw Every CSS Property You Know At It</strong></h2>
<p>Why use <em>one</em> CSS property when 17 might do the trick? Combine <code>margin: auto;</code>, <code>position: absolute;</code>, <code>transform: translate(-50%, -50%);</code>, <code>display: table-cell;</code>, and <code>vertical-align: middle;</code> into a single class. Bonus points if you add <code>float: left;</code> "just in case." Watch in awe as your <code>div</code> teleports to Narnia, crashes the browser, or—in rare cases—centers itself… but only on your local library’s 2003 Dell PC running IE8.</p>
<h2 id="heading-2-use-margins-like-a-gambling-addict"><strong>2. Use Margins Like a Gambling Addict</strong></h2>
<p><em>“margin: 0 auto; should work, right?”</em> you whisper, as you refresh the page for the 45th time. But wait! You forgot to set a <code>width</code> on the <code>div</code>. No problem! Just apply <code>margin: 12% 34% 56% 78%;</code> and pray to the CSS overlords that math isn’t real. When the <code>div</code> inevitably ends up halfway off-screen, blame the user’s font size.</p>
<h2 id="heading-3-embrace-the-power-of-tables"><strong>3. Embrace the Power of Tables</strong></h2>
<p>Who needs flexbox or grid when you can resurrect the undead corpse of 1990s web design? Wrap your <code>div</code> in 17 nested <code>&lt;table&gt;</code> tags, apply <code>align="center"</code>, and watch as observers slowly back away from your code. For extra chaos, use <code>&lt;marquee&gt;</code> to make the centered <code>div</code> scroll diagonally. Accessibility? Never heard of her.</p>
<h2 id="heading-4-position-absolute-and-guess"><strong>4. Position: Absolute; and Guess</strong></h2>
<p>Set <code>position: absolute;</code> and then randomly assign <code>top:</code>, <code>left:</code>, <code>right:</code>, and <code>bottom:</code> values like you’re playing CSS bingo. “Maybe <code>left: 47%;</code> will do it?” Spoiler: It won’t. But hey, at least your <code>div</code> now hangs off the edge of the page like a modern art masterpiece.</p>
<h2 id="heading-5-flexbox-overcomplication"><strong>5. Flexbox Overcomplication</strong></h2>
<p>Flexbox is supposed to make centering easy, but where’s the fun in that? Apply <code>display: flex;</code> to the parent, then add <code>justify-content: space-between;</code>, <code>align-items: stretch;</code>, and <code>flex-direction: column-reverse;</code>. When the <code>div</code> still isn’t centered, add <code>transform: rotate(180deg);</code> and declare, “It’s a feature.”</p>
<h2 id="heading-6-the-important-hammer"><strong>6. The !important Hammer</strong></h2>
<p>When all else fails, smash that <code>!important</code> button like it’s the last cupcake at a developer meetup. <code>margin-left: 50% !important; width: 200px !important; position: static !important;</code> Watch as your stylesheet becomes a ticking time bomb of specificity wars. Future you will <em>love</em> debugging this.</p>
<h2 id="heading-7-javascript-because-css-is-too-mainstream"><strong>7. JavaScript: Because CSS is Too Mainstream</strong></h2>
<p>Why write CSS when you can write 30 lines of JavaScript to calculate the viewport width, divide by π, and dynamically inject inline styles? Sure, your <code>div</code> now centers… after a 3-second lag. But at least you’ve justified using React for a static HTML page.</p>
<h2 id="heading-8-beg-and-bribe-the-div"><strong>8. Beg and Bribe the Div</strong></h2>
<p>Sometimes, kindness wins. Add a CSS comment: <code>/* Please center yourself, I beg you */</code>. If that fails, try whispering sweet nothings to your monitor or offering the <code>div</code> a samosa.</p>
<h2 id="heading-9-sweep-it-under-the-dom">9. Sweep it under the DOM</h2>
<p>If all else fails, <code>display: none;</code> and pretend it was never there. Because you need to only center what is present in this material world.</p>
<h2 id="heading-in-conclusion"><strong>In Conclusion</strong></h2>
<p>Centering a <code>div</code> is a spiritual journey that teaches patience, humility, and the importance of Googling “<a target="_blank" href="https://letmegooglethat.com/?q=how+to+center+a+div">how to center a div</a>” for the 900th time. But if you <em>must</em> know one of the "right" ways (boo, boring!), here’s the secret incantation:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.parent</span> {  
  <span class="hljs-attribute">display</span>: flex;  
  <span class="hljs-attribute">justify-content</span>: center; <span class="hljs-comment">/* sorcery */</span>  
  <span class="hljs-attribute">align-items</span>: center;     <span class="hljs-comment">/* dark magic */</span>  
}
</code></pre>
<p>…but beware: this method is so straightforward, it might accidentally leave you with <em>free time</em>. And then what? Learn another CSS property? Touch grass? Unthinkable.</p>
<p><em>—Written by a developer who once centered a div on the first try (it was a hallucination).</em></p>
]]></content:encoded></item><item><title><![CDATA[A Programmer's Setup: How to Never Touch Your Arrow Keys Again]]></title><description><![CDATA[As developers, we spend countless hours hunched over our keyboards, meticulously crafting lines of code, and navigating through sprawling codebases. Some of us spend exorbitant amounts to buy (or even build) custom keyboards. But, rarely does most of...]]></description><link>https://blog.jyuvaraj.com/a-programmers-setup-how-to-never-touch-your-arrow-keys-again</link><guid isPermaLink="true">https://blog.jyuvaraj.com/a-programmers-setup-how-to-never-touch-your-arrow-keys-again</guid><category><![CDATA[keyboard shortcuts]]></category><category><![CDATA[keyboard mapping]]></category><category><![CDATA[keyboard]]></category><category><![CDATA[Shortcuts]]></category><category><![CDATA[vim]]></category><dc:creator><![CDATA[Yuvaraj J]]></dc:creator><pubDate>Tue, 12 Sep 2023 15:25:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cUIl28-EWeI/upload/ac629e8ae15cb34b52b0a65fe121f8cc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As developers, we spend countless hours hunched over our keyboards, meticulously crafting lines of code, and navigating through sprawling codebases. Some of us spend exorbitant amounts to buy (or even build) custom keyboards. But, rarely does most of us think about the ergonomics of our daily tool.</p>
<h1 id="heading-home-row-motion-keys">Home Row Motion Keys</h1>
<p>If you have used <a target="_blank" href="https://www.vim.org/">Vim</a> before, you will attest to the fact that using <strong>Vim's motion keys</strong> (<code>h</code>, <code>j</code>, <code>k</code>, <code>l</code>) on the home row is much quicker and reduces the strain on your wrists. For those of you who haven't used Vim, let me introduce you to the pleasures of such a setup.</p>
<p>The setup I'm about to introduce uses the same Vim motions to control all the actions you would normally do with your arrow keys -- move left, move right, select one word, select the top line, or any arrow key action you can name. By the end of this article, you can pull the arrow keys out of your keyboard and throw them away!</p>
<p>For those of you new to touch-typing and Vim, allow me to give a quick introduction to the home row and Vim's motion keys. The home row is the center row on a keyboard. Your left-hand fingers rest on <code>a</code>, <code>s</code>, <code>d</code>, and <code>f</code>, while your right-hand fingers rest on <code>j</code>, <code>k</code>, <code>l</code>, and <code>;</code> keys. In Vim, the motion keys replacing the arrow keys are as follows:</p>
<ul>
<li><p>← : <code>h</code></p>
</li>
<li><p>↓ : <code>j</code></p>
</li>
<li><p>↑ : <code>k</code></p>
</li>
<li><p>→ : <code>l</code></p>
</li>
</ul>
<h1 id="heading-the-setup">The Setup</h1>
<p>As you know, holding down on <code>Ctrl</code> key allows us to modify the behavior of other keys. For example, pressing the <code>C</code> key directly will type out the letter "c", whereas if you hold <code>Ctrl</code> and then press the <code>C</code> key will copy the selected area.</p>
<p>We can leverage our knowledge of such modifier keys and create our super-keyboard. Instead of relying only on the standard modifier keys (<code>Ctrl</code>, <code>Alt</code>, <code>Super</code>, <code>Fn</code>), we can create our own modifier keys!</p>
<h2 id="heading-f-mode">f-mode</h2>
<p>When you are resting your hand on the home row like a touch typist would, your left index finger should be resting on the <code>F</code> key. Why not use this key as a modifier key instead of its normal function of using it to type "f"? You might argue that the <code>F</code> key is very important to you as you cannot <a target="_blank" href="https://en.wikipedia.org/wiki/Press_F_to_pay_respects">pay respects</a> without it.</p>
<p>Fortunately, most key remappers allow us to map the same key to multiple functions depending on whether it is being held or tapped. For example, below is a <strong>keyd</strong> configuration that overloads the Capslock key to become <code>Ctrl</code> when held for more than <em>200ms</em>, but remain as Capslock when just tapped:</p>
<pre><code class="lang-nix"><span class="hljs-attr">capslock</span> = overloadt(control, capslock, <span class="hljs-number">200</span>)
</code></pre>
<p>In this manner, we can overload the <code>F</code> key to act as a <em>modifier</em> called <code>nav</code> when being held and act as plain old <code>F</code> when being tapped.</p>
<pre><code class="lang-nix"><span class="hljs-attr">f</span> = overloadt(nav, f, <span class="hljs-number">200</span>)
</code></pre>
<p>Just like how the <code>Ctrl</code> modifier modifies the <code>C</code> key's behavior, our custom <code>nav</code> modifier can modify other keys to give our custom behavior. In this setup, I have made the <code>nav</code> modifier to modify as below:</p>
<ul>
<li><p><code>H</code>: <code>left</code></p>
</li>
<li><p><code>J</code>: <code>down</code></p>
</li>
<li><p><code>K</code>: <code>up</code></p>
</li>
<li><p><code>L</code>: <code>right</code></p>
</li>
<li><p><code>Y</code>: <code>Home</code></p>
</li>
<li><p><code>O</code>: <code>End</code></p>
</li>
</ul>
<pre><code class="lang-nix">[nav]

<span class="hljs-attr">h</span> = left
<span class="hljs-attr">j</span> = down
<span class="hljs-attr">k</span> = up
<span class="hljs-attr">l</span> = right
<span class="hljs-attr">y</span> = home
<span class="hljs-attr">o</span> = end
</code></pre>
<p>So, if you hold down your <code>F</code> key and then tap <code>K</code>, you will now mimic the <code>up</code> arrow action! We've replicated the arrow key motions from the comfort of our home row. No more stretching your wrist to access the arrow keys!us</p>
<h2 id="heading-d-mode">d-mode</h2>
<p>"Wait, I can move by holding down <code>F</code> and pressing one of the Vim motion keys (h, j, k, l). But how do I replicate the Shift+Arrow key functionality?" you ask.</p>
<p>If you haven't used the Shift+Arrow combination, here's what it does. In a text editor, if you press Shift + Left Arrow, you can select the character to the left of your cursor.</p>
<p>Here's how we replicate this in our setup. Just like how <code>nav</code> was a new modifier we created, we will also create another modifier called <code>select_nav</code> which will be activated by holding down the <code>D</code> key.</p>
<pre><code class="lang-nix"><span class="hljs-attr">d</span> = overloadt(select_nav, d, <span class="hljs-number">200</span>)
</code></pre>
<p>The same directional definitions in the <strong>f-mode</strong> are used here: (<code>H</code> = <code>left</code>, <code>J</code> = <code>down</code>, ..).</p>
<pre><code class="lang-nix">[select_nav]

<span class="hljs-attr">h</span> = S-left
<span class="hljs-attr">k</span> = S-up
<span class="hljs-attr">j</span> = S-down
<span class="hljs-attr">l</span> = S-right
<span class="hljs-attr">y</span> = S-home
<span class="hljs-attr">o</span> = S-end
</code></pre>
<h2 id="heading-a-mode-and-s-mode">a-mode and s-mode</h2>
<p>If you want to take this even further, we also have the <strong>a-mode</strong> (<code>word_nav</code>) and <strong>s-mode</strong> (<code>select_word_nav</code>).</p>
<p><strong>a-mode</strong> allows us to move directionally word-by-word instead of character-by-character.</p>
<pre><code class="lang-nix"><span class="hljs-attr">a</span> = overloadt(word_nav, a, <span class="hljs-number">200</span>)

[word_nav]

<span class="hljs-attr">h</span> = C-left
<span class="hljs-attr">k</span> = C-up
<span class="hljs-attr">j</span> = C-down
<span class="hljs-attr">l</span> = C-right
<span class="hljs-attr">y</span> = C-home
<span class="hljs-attr">o</span> = C-end
</code></pre>
<p>And <strong>s-mode</strong> allows us to select directionally word-by-word.</p>
<pre><code class="lang-nix"><span class="hljs-attr">s</span> = overloadt(select_word_nav, s, <span class="hljs-number">200</span>)

[select_word_nav]

<span class="hljs-attr">h</span> = C-S-left
<span class="hljs-attr">k</span> = C-S-up
<span class="hljs-attr">j</span> = C-S-down
<span class="hljs-attr">l</span> = C-S-right
<span class="hljs-attr">y</span> = C-S-home
<span class="hljs-attr">o</span> = C-S-end
</code></pre>
<h1 id="heading-installation">Installation</h1>
<p>As we will be remapping the keys, we will be installing a key-remapping solution. For Linux, my choice (after much experimentation) is <a target="_blank" href="https://github.com/rvaiya/keyd">keyd</a> (the examples above are keyd configs).</p>
<p><em>Note:</em> If anyone using Mac OS X is interested, please comment below as I do have a similar setup using <a target="_blank" href="https://karabiner-elements.pqrs.org/"><strong>Karabiner-Elements</strong></a> that I can share.</p>
<p>To use, follow the below steps:</p>
<ul>
<li>Install <strong>keyd</strong> service using the following commands:</li>
</ul>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/rvaiya/keyd
<span class="hljs-built_in">cd</span> keyd
make &amp;&amp; sudo make install
sudo systemctl <span class="hljs-built_in">enable</span> keyd &amp;&amp; sudo systemctl start keyd
</code></pre>
<p>This installs the <code>keyd</code> service and enables it to activate on startup.</p>
<ul>
<li>Now, we need to configure the key remappings. Paste the following in <code>/etc/keyd/default.conf</code>. You can also <a target="_blank" href="https://gist.github.com/jyuvaraj03/15fdf284bb97e9227fc50b5128072139">star this gist</a> with the keyd.conf code.</li>
</ul>
<pre><code class="lang-nix">[ids]

*

[global]

<span class="hljs-attr">chord_timeout</span> = <span class="hljs-number">100</span>

[main]

<span class="hljs-comment"># Layer keys that act as themselves if not held for more than 200ms.</span>
<span class="hljs-attr">f</span> = overloadt(nav, f, <span class="hljs-number">200</span>)
<span class="hljs-attr">d</span> = overloadt(select_nav, d, <span class="hljs-number">200</span>)
<span class="hljs-attr">s</span> = overloadt(select_word_nav, s, <span class="hljs-number">200</span>)
<span class="hljs-attr">a</span> = overloadt(word_nav, a, <span class="hljs-number">200</span>)

[nav]

<span class="hljs-attr">h</span> = left
<span class="hljs-attr">k</span> = up
<span class="hljs-attr">j</span> = down
<span class="hljs-attr">l</span> = right
<span class="hljs-attr">y</span> = home
<span class="hljs-attr">o</span> = end

[select_nav]

<span class="hljs-attr">h</span> = S-left
<span class="hljs-attr">k</span> = S-up
<span class="hljs-attr">j</span> = S-down
<span class="hljs-attr">l</span> = S-right
<span class="hljs-attr">y</span> = S-home
<span class="hljs-attr">o</span> = S-end

[select_word_nav]

<span class="hljs-attr">h</span> = C-S-left
<span class="hljs-attr">k</span> = C-S-up
<span class="hljs-attr">j</span> = C-S-down
<span class="hljs-attr">l</span> = C-S-right
<span class="hljs-attr">y</span> = C-S-home
<span class="hljs-attr">o</span> = C-S-end

[word_nav]

<span class="hljs-attr">h</span> = C-left
<span class="hljs-attr">k</span> = C-up
<span class="hljs-attr">j</span> = C-down
<span class="hljs-attr">l</span> = C-right
<span class="hljs-attr">y</span> = C-home
<span class="hljs-attr">o</span> = C-end

<span class="hljs-comment"># Mapping the custom modifier keys to themselves to make those actions </span>
<span class="hljs-comment"># instantaneous instead of waiting for the timeout</span>
[shift]

<span class="hljs-attr">f</span> = F
<span class="hljs-attr">d</span> = D
<span class="hljs-attr">s</span> = S
<span class="hljs-attr">a</span> = A

[control]

<span class="hljs-attr">f</span> = C-f
<span class="hljs-attr">d</span> = C-d
<span class="hljs-attr">s</span> = C-s
<span class="hljs-attr">a</span> = C-a

[control+shift]

<span class="hljs-attr">f</span> = C-S-f
<span class="hljs-attr">d</span> = C-S-d
<span class="hljs-attr">s</span> = C-S-s
<span class="hljs-attr">a</span> = C-s-a
</code></pre>
<ul>
<li>Run <code>sudo keyd reload</code> to reload the new config and voila! You can now pull out your arrow keys as promised!</li>
</ul>
]]></content:encoded></item></channel></rss>