<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rajasegar Chandran</title>
    <description>The latest articles on Forem by Rajasegar Chandran (@rajasegar).</description>
    <link>https://forem.com/rajasegar</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%2F245061%2F5ab1577f-a443-4375-8db4-1633d25b50f7.png</url>
      <title>Forem: Rajasegar Chandran</title>
      <link>https://forem.com/rajasegar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rajasegar"/>
    <language>en</language>
    <item>
      <title>React inside Ember - The Second Chapter</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Fri, 12 Jul 2024 07:21:49 +0000</pubDate>
      <link>https://forem.com/rajasegar/react-inside-ember-the-second-chapter-17bl</link>
      <guid>https://forem.com/rajasegar/react-inside-ember-the-second-chapter-17bl</guid>
      <description>&lt;p&gt;A year ago, I wrote an article here about invoking React components from Ember where I outlined an approach of rendering React components inside Ember templates or components using a complex and sophisticated mechanism. &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/rajasegar" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F245061%2F5ab1577f-a443-4375-8db4-1633d25b50f7.png" alt="rajasegar"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/rajasegar/invoking-react-components-from-your-ember-apps-3fgg" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Invoking React components from your Ember apps&lt;/h2&gt;
      &lt;h3&gt;Rajasegar Chandran ・ Jan 31 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ember&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webpack&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;After trying it out in our organization, we have found that there are a lot of downsides and productivity concerns in implementing that approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations of the old approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Converting existing repo to a workspace or monorepo&lt;/li&gt;
&lt;li&gt;Setup complex build tooling with webpack&lt;/li&gt;
&lt;li&gt;Extra wrapper components for passing in props&lt;/li&gt;
&lt;li&gt;No hot module reloading support&lt;/li&gt;
&lt;li&gt;Cannot yield child components from Ember&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advantages of the new approach
&lt;/h2&gt;

&lt;p&gt;With the new addon approach by using the &lt;code&gt;ember-react-fc&lt;/code&gt; addon, the process looks much simpler and we can overcome many downsides that were outlined in the previous post. Let's discuss the advantages of the new approach one by one here in detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg89o3sw6n5n44f2d7gm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg89o3sw6n5n44f2d7gm.png" alt="Image description" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  No workspace or monorepo setup required
&lt;/h3&gt;

&lt;p&gt;With this new approach, you don't have to convert your repo to a monorepo or workspace like we did in the old one. You can simply put your React components inside the &lt;code&gt;app/components&lt;/code&gt;, may be with a new namespace like &lt;code&gt;app/components/react&lt;/code&gt; and use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;React::HelloWorld&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Raja"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  No complex setup required
&lt;/h3&gt;

&lt;p&gt;Previously, we have been compiling React component code using babel plugins using webpack config in Ember cli using the auto-import plugin. The problem with this approach is that, we need to install a lot of dependencies like babel plugins, react libraries and have to configure the webpack in such a way that it picks up only the files with JSX extensions referred from a different package inside a workspace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foexaxeep4a9wylzyxpj3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foexaxeep4a9wylzyxpj3.jpg" alt="Image description" width="701" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ember-react-fc
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/rajasegar/ember-react-fc" rel="noopener noreferrer"&gt;ember-react-fc&lt;/a&gt; is an Ember addon to incrementally migrate your Ember code starting from components to React. This addon supports the latest React version 18 and functional components. The addon takes care of a lot of things like adding the respective babel plugins to compile JSX, react and react-dom dependencies to your Ember projects, support for &lt;code&gt;.jsx&lt;/code&gt; extensions inside your Ember apps and so on.&lt;/p&gt;

&lt;p&gt;You can install it in your Ember projects like below and start writing your components in React and they will work out of the box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ember install ember-react-fc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This addon also comes with a component blueprint so that you can also generate component boiler plates for your React component.&lt;/p&gt;

&lt;p&gt;You can generate React components like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ember generate react-component hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  No wrapper components required
&lt;/h3&gt;

&lt;p&gt;In the old approach, we need to create Ember wrapper components for each React component we were creating. This creates an unnecessary overhead to have Ember duplicates for React components. But with this approach we are just invoking React components inside Ember templates and components in Ember way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;I am a Ember Component&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;HelloReact&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;toggle&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automatic reloading
&lt;/h3&gt;

&lt;p&gt;In the old approach, we have kept our React components inside a (yarn or pnpm) workspace, so the changes inside this workspace won't affect the Ember build. Since Ember will only look for changes inside the &lt;code&gt;app/&lt;/code&gt; folder, it was proving very difficult to propagate the changes in React components to Ember build pipeline.&lt;/p&gt;

&lt;p&gt;This problem we overcame in the new approach since we are keeping the React components inside the Ember app itself, any change you make to your React components will automatically get picked up by ember-cli.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpv6rgcvio0jrihoo8pye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpv6rgcvio0jrihoo8pye.png" alt="Image description" width="800" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  React can have Ember children
&lt;/h3&gt;

&lt;p&gt;There was no way previously to pass Ember components as children to React components in the old approach. But now you can put Ember components inside React as children. There is some room for misunderstanding here. What I meant by using Ember components as children is that when you are using the markup in your Ember templates, you can give Ember components as children to React components but not inside JSX in React.&lt;/p&gt;

&lt;p&gt;This will work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;React::HelloWorld&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Raja"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;MyEmberComponent&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;arg1=&lt;/span&gt;&lt;span class="s"&gt;"abc"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;arg2=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/React::HelloWorld&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This won't work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;WithEmberSupport&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ember-react-fc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nc"&gt;WithEmberSupport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;FunctionalComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"wrapper"&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Toggle&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;you said: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyEmberComponent&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"abc"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="na"&gt;true&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a sample Ember app with the addon &lt;code&gt;ember-react-fc&lt;/code&gt; installed and React components created and rendered inside Ember templates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8l747mztl3hmxwl4580.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8l747mztl3hmxwl4580.gif" alt="Image description" width="938" height="840"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;The inspiration for this addon came from previous works by &lt;a href="https://github.com/alexlafroscia" rel="noopener noreferrer"&gt;Alex LaFroscia&lt;/a&gt; like &lt;a href="https://github.com/alexlafroscia/ember-react-components" rel="noopener noreferrer"&gt;ember-react-components&lt;/a&gt;. But that project got abandoned some 3 years ago and it is not made for the latest React versions. I cleaned up the addon by removing the logic for class components, made it work with latest React v18, fixed some issues and so on.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the post and let me know your feedback and thoughts in the comment section. Please give the addon a try and let me know for any issues.&lt;/p&gt;

</description>
      <category>react</category>
      <category>ember</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Vim-style repeatable key bindings for navigating windows in Emacs</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Thu, 06 Jun 2024 05:51:00 +0000</pubDate>
      <link>https://forem.com/rajasegar/vim-style-repeatable-key-bindings-for-navigating-windows-in-emacs-5c4l</link>
      <guid>https://forem.com/rajasegar/vim-style-repeatable-key-bindings-for-navigating-windows-in-emacs-5c4l</guid>
      <description>&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt; Vim-style repeatable key bindings for navigating windows in Emacs

&lt;ol&gt;
&lt;li&gt; Navigating windows in Emacs
&lt;/li&gt;
&lt;li&gt; windmove
&lt;/li&gt;
&lt;li&gt; repeat-mode
&lt;/li&gt;
&lt;li&gt; Key bindings
&lt;/li&gt;
&lt;li&gt; References
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a id="orge85934e"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Vim-style repeatable key bindings for navigating windows in Emacs
&lt;/h1&gt;

&lt;p&gt;In this post we are going to see how to create easily accessible&lt;br&gt;
key bindings for jumping around windows inside Emacs in a directional manner. We are also going to make this key bindings repeatable to make the navigation awesome, along with Vim-style navigation using h,j,k,l keys &lt;/p&gt;

&lt;p&gt;&lt;a id="org9ab4f54"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Navigating windows in Emacs
&lt;/h2&gt;

&lt;p&gt;Before I came up with this workflow, I have been using &lt;code&gt;C-x o&lt;/code&gt; to switch to windows in Emacs. The biggest problem with this for me is to complete the window cycle to switch to the desired window which is the immediate left window from my current one. I stumbled across the &lt;code&gt;windmove&lt;/code&gt; commands and start using them. Finally I came up with an intuitive key binding in Vim style to use the home row keys like h,j,k,l&lt;/p&gt;

&lt;p&gt;&lt;a id="orge3556e7"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  windmove
&lt;/h2&gt;

&lt;p&gt;Windmove is a library built into GnuEmacs starting with version 21.&lt;br&gt;
It lets you move point from window to window using Shift and the arrow keys. This is easier to type than ‘C-x o’ and, for some users, may be more intuitive. To activate all these keybindings, add the following to your InitFile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;fboundp&lt;/span&gt; &lt;span class="ss"&gt;'windmove-default-keybindings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;windmove-default-keybindings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also might need to enable &lt;code&gt;windmove-wrap-around&lt;/code&gt; setting if you wish to enable wrapping around window navigation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;windmove-wrap-around&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setting will control whether movement off the edge of the frame wraps around. If this variable is set to t, moving left from the leftmost window in a frame will find the rightmost one, and similarly for the other directions.&lt;/p&gt;

&lt;p&gt;&lt;a id="org0e39f4f"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  repeat-mode
&lt;/h2&gt;

&lt;p&gt;repeat-mode is a global minor mode.&lt;br&gt;
When Repeat mode is enabled, certain commands bound to multi-key&lt;br&gt;
sequences can be repeated by typing a single key, after typing the&lt;br&gt;
full key sequence once. The commands which can be repeated like that are those whose symbol has the property ‘repeat-map’ which specifies a keymap of single keys for repeating.&lt;/p&gt;

&lt;p&gt;You can check out the current repeat maps enabled in your Emacs with &lt;code&gt;M-x describe-repeat-maps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Please ensure you have enabled repeat-mode in your Emacs config by adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;repeat-mode&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a id="org0158bd7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key bindings
&lt;/h2&gt;

&lt;p&gt;Now let's take a look at mapping the windmove commands to simple&lt;br&gt;
keybindings starting with the &lt;code&gt;C-c w&lt;/code&gt; prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-set-key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;"C-c w h"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'windmove-left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-set-key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;"C-c w j"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'windmove-down&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-set-key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;"C-c w k"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'windmove-up&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-set-key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt; &lt;span class="s"&gt;"C-c w l"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;'windmove-right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to make the key bindings repeatable we have to define a new repeat-map using the &lt;code&gt;defvar-keymap&lt;/code&gt; function with the repeat property set to true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;defvar-keymap&lt;/span&gt; &lt;span class="nv"&gt;windmove-repeat-map&lt;/span&gt;
    &lt;span class="ss"&gt;:repeat&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
    &lt;span class="s"&gt;"h"&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;windmove-left&lt;/span&gt;
    &lt;span class="s"&gt;"j"&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;windmove-down&lt;/span&gt;
    &lt;span class="s"&gt;"k"&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;windmove-up&lt;/span&gt;
    &lt;span class="s"&gt;"l"&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;windmove-right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope you enjoyed the post and the new key bindings are helpful for you to navigate your windows in Emacs. Please let me know your thoughts and feedback in the comments section&lt;/p&gt;

&lt;p&gt;&lt;a id="orgcf3d17f"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.emacswiki.org/emacs/WindMove" rel="noopener noreferrer"&gt;https://www.emacswiki.org/emacs/WindMove&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://karthinks.com/software/emacs-window-management-almanac/" rel="noopener noreferrer"&gt;https://karthinks.com/software/emacs-window-management-almanac/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://karthinks.com/software/it-bears-repeating/" rel="noopener noreferrer"&gt;https://karthinks.com/software/it-bears-repeating/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>emacs</category>
      <category>vim</category>
    </item>
    <item>
      <title>Exploring Syntax Trees in Emacs with Tree-sitter</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Tue, 14 May 2024 06:24:19 +0000</pubDate>
      <link>https://forem.com/rajasegar/exploring-asts-in-emacs-with-tree-sitter-fg1</link>
      <guid>https://forem.com/rajasegar/exploring-asts-in-emacs-with-tree-sitter-fg1</guid>
      <description>&lt;p&gt;In this post, we are going to take a look at an awesome feature in Emacs for exploring Syntax Trees using Treesitter. Before diving into the topic let's set some context.&lt;/p&gt;

&lt;p&gt;I am a big fan of ASTs due to the application of them to solve complex problems like doing large scale migrations and code transformations in a big codebase. These code modifications are candidly known as "codemods". Since I am a codemod enthusiast, ASTs are are my bread and butter. I am also maintaining an awesome list of codemods &lt;a href="https://github.com/rajasegar/awesome-codemods" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract Syntax Trees
&lt;/h2&gt;

&lt;p&gt;An abstract syntax tree (AST) serves as a data structure employed to depict the arrangement of a program or code snippet. It offers a tree-shaped representation of the essential syntactic structure of text, often code composed in a formal language. Each node within the tree signifies a construct present in the text, sometimes simply referred to as a syntax tree.&lt;/p&gt;

&lt;p&gt;The term "abstract" in this context implies that it captures the fundamental structural or content-related aspects rather than every minutiae found in the actual syntax. For example, grouping parentheses are inferred within the tree structure, eliminating the need for them to be represented as distinct nodes. Similarly, a syntactic entity like an if-condition-then statement might be represented by a solitary node with three branches.&lt;/p&gt;

&lt;p&gt;This sets apart abstract syntax trees from concrete syntax trees, conventionally known as parse trees. Parse trees are typically constructed by a parser during the translation and compilation of source code. Subsequent processing, such as contextual analysis, supplements the AST with additional information.&lt;/p&gt;

&lt;p&gt;Beyond their initial purpose, abstract syntax trees find application in program analysis and transformation systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emacs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/" rel="noopener noreferrer"&gt;Emacs&lt;/a&gt; is a highly extensible, customizable, and powerful text editor primarily used in the field of software development and computer programming. Developed by Richard Stallman and initially released in the 1970s, Emacs has since evolved into a versatile platform offering a wide array of features beyond basic text editing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6b2hbsv6vzq821zkkwoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6b2hbsv6vzq821zkkwoq.png" alt="Image description" width="128" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of Emacs's defining characteristics is its capability for extensive customization and extension using its built-in Lisp programming language. Users can tailor Emacs to suit their specific needs by writing or installing custom scripts and packages, enabling functionalities such as syntax highlighting, code completion, version control integration, and much more.&lt;/p&gt;

&lt;p&gt;Emacs also offers a range of advanced editing features, including multiple buffers and windows, macro recording and playback, search and replace with regular expressions, and support for various programming languages and markup formats.&lt;/p&gt;

&lt;p&gt;Moreover, Emacs provides a range of built-in modes and tools for various tasks, such as programming, text formatting, email, web browsing, and even games. It has a steep learning curve due to its extensive feature set and the need to become proficient with its keybindings and commands, but many users find that the investment pays off in terms of productivity and efficiency once mastered.&lt;/p&gt;

&lt;p&gt;Emacs is available on various platforms, including Unix-like operating systems (such as Linux and macOS), Windows, and others, making it a popular choice among developers and power users across different computing environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treesitter
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/tree-sitter" rel="noopener noreferrer"&gt;Tree-sitter&lt;/a&gt; is a parsing system and incremental parser generator framework primarily used for programming language processing. Developed by the GitHub team, it provides robust and efficient parsing capabilities for various programming languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49j2veabatvgpyihxpre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49j2veabatvgpyihxpre.png" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At its core, Tree-sitter employs a bottom-up parsing approach to construct Abstract Syntax Trees (ASTs) for source code. What sets it apart is its incremental parsing feature, which enables it to update the AST incrementally as the source code changes, offering significant performance advantages over traditional parsing techniques.&lt;/p&gt;

&lt;p&gt;Tree-sitter is designed to be highly efficient, making it suitable for use cases where real-time or near-real-time parsing is required, such as in code editors and IDEs. Its incremental parsing capability allows code editors to provide features like syntax highlighting, code folding, code navigation, and intelligent code completion with minimal delay, even for large codebases.&lt;/p&gt;

&lt;p&gt;Furthermore, Tree-sitter's parsing rules are defined using a declarative domain-specific language, making it easy to specify grammars for new programming languages or customize existing grammars. This flexibility allows Tree-sitter to support a wide range of programming languages and dialects.&lt;/p&gt;

&lt;p&gt;Overall, Tree-sitter is a powerful tool for parsing and analyzing source code efficiently, making it a popular choice among developers building code editors, IDEs, static analysis tools, and other language processing applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  treesit-explore-mode
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;treesit-explore-mode&lt;/code&gt; is a feature in Emacs that provides a graphical interface for exploring and interacting with syntax trees generated by the Tree-sitter parsing system. This mode is particularly useful for developers who work with programming languages supported by Tree-sitter and want to visually inspect the structure of their code.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/VHeb2GFVEZQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;When activated, &lt;code&gt;treesit-explore-mode&lt;/code&gt; displays the syntax tree of the current buffer in a separate buffer, usually split vertically or horizontally alongside the original code buffer. The syntax tree is represented as a hierarchical structure, where each node corresponds to a syntactic construct in the code, such as functions, loops, conditionals, and expressions.&lt;/p&gt;

&lt;p&gt;The graphical interface of &lt;code&gt;treesit-explore-mode&lt;/code&gt; allows users to navigate through the syntax tree, expand and collapse nodes, and inspect the properties of individual nodes. This can be helpful for understanding the structure of complex code, identifying syntax errors, or debugging issues related to syntax highlighting or code analysis.&lt;/p&gt;

&lt;p&gt;Additionally, &lt;code&gt;treesit-explore-mode&lt;/code&gt; may provide features for interacting with the syntax tree, such as highlighting nodes corresponding to the current cursor position in the code buffer, or providing context-sensitive information about selected nodes.&lt;/p&gt;

&lt;p&gt;Overall, &lt;code&gt;treesit-explore-mode&lt;/code&gt; enhances the development experience in Emacs by providing a convenient way to visualize and explore syntax trees generated by Tree-sitter, facilitating code comprehension and analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  treesit-inspect-mode
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;treesit-inspect-mode&lt;/code&gt; in Emacs is a feature designed to provide detailed information and interactive exploration capabilities for syntax trees generated by the Tree-sitter parsing system. Similar to &lt;code&gt;treesit-explore-mode&lt;/code&gt;, this mode is particularly useful for developers working with programming languages supported by Tree-sitter who want to gain insights into the structure of their code.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/fus6EW3Y8as"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;When activated, &lt;code&gt;treesit-inspect-mode&lt;/code&gt; displays information about the syntax tree in a separate buffer, typically alongside the original code buffer. This information may include details about the current node under the cursor, such as its type, properties, and position within the syntax tree hierarchy.&lt;/p&gt;

&lt;p&gt;One of the primary functionalities of &lt;code&gt;treesit-inspect-mode&lt;/code&gt; is to allow users to inspect the properties of individual nodes within the syntax tree interactively. &lt;/p&gt;

&lt;p&gt;Overall, &lt;code&gt;treesit-inspect-mode&lt;/code&gt; complements the functionality of &lt;code&gt;treesit-explore-mode&lt;/code&gt; by offering a focused and detailed view of syntax trees, enabling developers to gain deeper insights into the structure of their code and facilitating tasks such as debugging, code analysis, and comprehension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;So we have seen what tree-sitter and its capabilities inside Emacs. Previously before using tree-sitter for exploring ASTs, I have been using something like &lt;a href="//htts://ast-explorer.net"&gt;AST Explorer&lt;/a&gt; for checking my ASTs. Since this comes within Emacs and I don't have to context-switch between the browser and my text editor to work with ASTs. This is really a productivity boost for my day-to-day job.&lt;/p&gt;

&lt;p&gt;Tell me what do you think about the tree-sitter in Emacs in the comments section. I am sure there a lot other things you can do with tree-sitter in Emacs other than exploring ASTs.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.masteringemacs.org/article/how-to-get-started-tree-%0Asitter" rel="noopener noreferrer"&gt;How to Get Started with Tree-Sitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://emacs-tree-sitter.github.io/" rel="noopener noreferrer"&gt;Emacs Tree-sitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>emacs</category>
      <category>programming</category>
      <category>treesitter</category>
    </item>
    <item>
      <title>Striking a Balance: Sensibility vs Convenience in Software Development</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Thu, 22 Feb 2024 04:44:17 +0000</pubDate>
      <link>https://forem.com/rajasegar/striking-a-balance-sensibility-vs-convenience-in-software-development-31og</link>
      <guid>https://forem.com/rajasegar/striking-a-balance-sensibility-vs-convenience-in-software-development-31og</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of software development, developers often find themselves at a crossroads between sensibility and convenience. The pursuit of creating efficient and robust software systems sometimes clashes with the desire for quick and easy solutions. Striking the right balance between sensibility and convenience is crucial for delivering high-quality software that meets user expectations and industry standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sensibility in Software Development:
&lt;/h2&gt;

&lt;p&gt;Sensibility in software development refers to the thoughtful consideration of design, architecture, and coding practices. It involves making decisions based on long-term benefits, maintainability, and scalability. Sensible software development aims to create solutions that stand the test of time and adapt to changing requirements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code Quality:&lt;/strong&gt;&lt;br&gt;
Writing clean, well-structured code is a fundamental aspect of sensibility. Code that adheres to best practices is easier to understand, maintain, and debug. Sensible developers prioritize readability and follow coding standards, fostering collaboration among team members and reducing the likelihood of introducing bugs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability and Performance:&lt;/strong&gt;&lt;br&gt;
Sensible software design takes into account scalability and performance considerations from the outset. Anticipating future growth and optimizing code for efficiency ensures that the software can handle increased user loads without sacrificing performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt;&lt;br&gt;
Security is a critical aspect of sensibility. A sensible approach involves proactive measures to identify and mitigate potential security risks. Regular code reviews, vulnerability assessments, and adherence to security best practices contribute to a robust defense against cyber threats.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Convenience in Software Development:
&lt;/h2&gt;

&lt;p&gt;Convenience, on the other hand, often involves making choices that prioritize short-term gains, speed of development, and ease of implementation. While convenience can lead to faster initial results, it may introduce challenges in the long run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rapid Prototyping:&lt;/strong&gt;&lt;br&gt;
Convenience plays a significant role in rapid prototyping and iterative development. Using frameworks and tools that expedite the development process allows for quick validation of ideas and concepts. However, it's crucial to reassess and refactor code as the project progresses to maintain sensibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Third-party Libraries and Frameworks:&lt;/strong&gt;&lt;br&gt;
Leveraging third-party libraries and frameworks can enhance convenience by saving development time and effort. However, it's essential to evaluate the long-term support and compatibility of these dependencies to avoid potential issues in future updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Short-term Solutions:&lt;/strong&gt;&lt;br&gt;
Quick fixes and workarounds may be convenient in the short term but can accumulate technical debt over time. Sensible developers weigh the trade-offs and address root causes, ensuring that solutions are not just convenient but sustainable in the long run.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Finding the Balance:
&lt;/h2&gt;

&lt;p&gt;Achieving the right balance between sensibility and convenience is an ongoing challenge for software developers. It requires a thoughtful approach that considers the specific needs of the project, the development team's capabilities, and the overall goals of the software.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prioritize Sensibility in Core Components:&lt;/strong&gt;&lt;br&gt;
Critical components of a software system, such as core algorithms, data structures, and security measures, should prioritize sensibility. Investing time and effort in these areas ensures a solid foundation for the entire project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Convenience Wisely:&lt;/strong&gt;&lt;br&gt;
Convenience can be a valuable ally when applied judiciously. Rapid prototyping, leveraging existing tools, and embracing agile development methodologies can streamline the development process without compromising long-term sensibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regular Refactoring:&lt;/strong&gt;&lt;br&gt;
Sensible software development includes a commitment to regular refactoring. As the project evolves, developers should revisit code, identify areas for improvement, and refactor as needed. This iterative process maintains sensibility while accommodating the convenience of rapid development.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;In the dynamic field of software development, the tension between sensibility and convenience is inevitable. Successful software projects require a careful balancing act, where sensibility guides the creation of a solid foundation, and convenience is employed thoughtfully to enhance productivity. By embracing both principles, developers can deliver software that not only meets immediate needs but also evolves gracefully to meet the challenges of the future.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Unraveling the Chapelle Salt Trap: A Cautionary Tale in Web Development</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Mon, 22 Jan 2024 05:59:26 +0000</pubDate>
      <link>https://forem.com/rajasegar/unraveling-the-chapelle-salt-trap-a-cautionary-tale-in-web-development-906</link>
      <guid>https://forem.com/rajasegar/unraveling-the-chapelle-salt-trap-a-cautionary-tale-in-web-development-906</guid>
      <description>&lt;p&gt;Web development is a constantly evolving field, and staying updated with the latest trends and technologies is crucial for success. However, amidst the rapid advancements, there are occasional pitfalls that can ensnare even the most experienced developers. In this blog post, we delve into the &lt;code&gt;Chapelle Salt Trap&lt;/code&gt;, a real-life scenario that highlights the importance of careful planning and diligent testing in web development projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Chapelle Salt Trap
&lt;/h2&gt;

&lt;p&gt;The Chapelle Salt Trap refers to a specific challenge often encountered during the development of complex web applications. It takes its name from the French term "chapeau de sel," or "hat of salt," which describes a geological formation where a layer of salt acts as a barrier, trapping hydrocarbons below the surface.&lt;/p&gt;

&lt;p&gt;Similar to its geological namesake, the Chapelle Salt Trap in web development represents an unforeseen issue in a software project that hinders progress and impedes the deployment of the desired features. This situation typically arises when a critical flaw or bottleneck is discovered relatively late in the development lifecycle, causing a significant delay or even a complete halt in the project's advancement.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Qspzg7-LOuY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Possible Causes of the Chapelle Salt Trap
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insufficient Planning&lt;/strong&gt;: One of the key contributors to the Chapelle Salt Trap is inadequate planning. Rushing into development without a solid strategy can lead to incomplete or ambiguous requirements, leaving room for potential issues and confusion down the line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Over-Reliance on External Dependencies&lt;/strong&gt;: Integrating external APIs, libraries, or services can boost productivity and add functionality to web applications. However, relying heavily on these external dependencies without thoroughly considering their reliability or scalability can be a recipe for disaster if issues arise unexpectedly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inadequate Testing&lt;/strong&gt;: Failing to implement comprehensive testing procedures throughout the development process is a common culprit behind the Chapelle Salt Trap. Insufficient or improperly executed testing fails to expose crucial bugs or performance issues until late stages, derailing progress and costing valuable time to fix the problems.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Mitigating the Chapelle Salt Trap
&lt;/h2&gt;

&lt;p&gt;While it may not be possible to completely eradicate the Chapelle Salt Trap, there are steps developers can take to minimize the likelihood of encountering this challenge:&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategic Planning
&lt;/h3&gt;

&lt;p&gt;Investing time in thorough planning, gathering comprehensive requirements, and creating a well-defined roadmap paves the way for a smoother development process. Regular communication with stakeholders and embracing agile methodologies like Scrum can help identify potential roadblocks early on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradual Integration of External Dependencies
&lt;/h3&gt;

&lt;p&gt;Instead of relying entirely on external dependencies, consider gradually integrating them into the project, allowing for better control and flexibility. Create fallback mechanisms for essential functionalities to prevent a complete halt if the dependencies encounter issues.&lt;/p&gt;

&lt;p&gt;Gradually integrating external dependencies in a web app is essential to ensure a smooth transition and minimize disruption. It refers to the process of adding external libraries, frameworks, or services to an existing web application incrementally rather than making drastic changes all at once. This approach allows developers to manage complexity, control risks, and maintain the overall stability and performance of the application.&lt;/p&gt;

&lt;p&gt;Here are a few key considerations and steps to follow when gradually integrating external dependencies in a web app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluate and plan&lt;/strong&gt;: Before adding any external dependencies, carefully assess their relevance, benefits, and impact on your web app. Consider factors like compatibility, maintainability, community support, learning curve, licensing, and performance. Plan the integration roadmap with a clear understanding of the dependencies and their potential risks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start small&lt;/strong&gt;: Begin by integrating a single dependency or a limited set of related dependencies. Choose something that offers immediate value and solves a specific problem in your application. This helps in gaining experience and understanding the impact of the integration on your codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Isolate and modularize&lt;/strong&gt;: To ensure a smooth integration, identify specific areas or components within your web app where the dependencies will be utilized. Modularize your application to segregate these areas and minimize the impact on the rest of the codebase. This helps in making the integration more manageable and easier to maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test and validate&lt;/strong&gt;: Thoroughly test the integration to verify its correctness, maintain existing functionality, and prevent regressions.Make sure to cover unit tests, integration tests, and functional tests to ensure the new dependencies integrate seamlessly with your existing codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitor and optimize&lt;/strong&gt;: Once the integration is complete, continuously monitor the performance and behavior of your web app. Monitor key metrics, such as response time, memory usage, and server load, to identify any potential bottlenecks or issues introduced by the new dependencies. Optimize and fine-tune the integration to maintain optimal performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document and train&lt;/strong&gt;: Proper documentation and knowledge sharing are crucial to ensure a smooth transition for your development team. Document the integration process, reference materials, and any known issues or workarounds. Conduct training sessions and share best practices to help your team understand and utilize the newly integrated dependencies effectively.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember, gradually integrating external dependencies is an iterative process. It requires ongoing maintenance, updates, and occasional refactoring to keep up with evolving dependencies and preserve the stability and performance of your web app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comprehensive Testing
&lt;/h3&gt;

&lt;p&gt;Implementing rigorous testing processes at each stage of development is paramount. Utilize unit testing, integration testing, load testing, and user acceptance testing to identify any issues as early as possible, reducing the chances of falling into the Chapelle Salt Trap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Chapelle Salt Trap serves as a &lt;code&gt;stark reminder&lt;/code&gt; of the challenges that web developers may encounter while developing complex software projects. By recognizing the potential causes and taking preventative measures, web development teams can mitigate the risks and ensure a smoother sail towards project completion.&lt;/p&gt;

&lt;p&gt;Consistent planning, judicious use of external dependencies, and a strong focus on comprehensive testing are all vital components in avoiding the Chapelle Salt Trap. By incorporating these best practices into their development processes, developers can minimize the likelihood of encountering unexpected obstacles, ensuring successful project delivery and client satisfaction.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating dynamic task runners for your npm scripts in Emacs</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Wed, 03 Jan 2024 08:58:05 +0000</pubDate>
      <link>https://forem.com/rajasegar/creating-dynamic-task-runners-for-your-npm-scripts-in-emacs-4e0c</link>
      <guid>https://forem.com/rajasegar/creating-dynamic-task-runners-for-your-npm-scripts-in-emacs-4e0c</guid>
      <description>&lt;p&gt;In this post, I will show you how to create dynamic task runners for your npm projects in Emacs. This is a simple example of how to use Emacs We are going to use prodigy for this example&lt;/p&gt;

&lt;p&gt;Usually inside an npm project we run the tasks from the package.json file from the &lt;code&gt;scripts&lt;/code&gt; section. A typical package.json file will look like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alacritty-themes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5.3.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Themes for Alacritty : A cross-platform GPU-Accelerated Terminal emulator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"alacritty-themes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./bin/cli.js"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git push &amp;amp;&amp;amp; git push --tags &amp;amp;&amp;amp; npm publish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint ."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"semantic-release"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"semantic-release"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mocha --recursive"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you want to run the lint task you will run the following in your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    npm run lint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are inside Emacs, you probably need to open a new terminal or &lt;code&gt;eshell&lt;/code&gt; buffer and manually type the above command. Also if want to run another command in parallel&lt;br&gt;
you need to open a separate buffer and run the command.&lt;/p&gt;

&lt;p&gt;So this involves a lot of manual work and it is not a very efficient way to do it. What if we can create a task runner that will run the tasks in parallel? What if we can do that in a way that will be dynamic? That is exactly what we are going to do here using a prodigy service.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prodigy
&lt;/h2&gt;

&lt;p&gt;What is prodigy? Prodigy is a framework for creating Emacs-based task runners. You can use it to manage external services from within Emacs. You can find more details in the  &lt;a href="https://github.com/rejeep/prodigy.el" rel="noopener noreferrer"&gt;prodigy documentation&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;To create new prodigy services you need to call the &lt;code&gt;prodigy-define-service&lt;/code&gt; function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;prodigy-define-service&lt;/span&gt;
    &lt;span class="ss"&gt;:command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&amp;amp;rest&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;plist-get&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt; &lt;span class="ss"&gt;:service&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                 &lt;span class="c1"&gt;;; ...&lt;/span&gt;
                 &lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let us see how we can achieve this using prodigy in Emacs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;'prodigy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;my/create-prodigy-service&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;package-manager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="s"&gt;"Create new prodigy services based on current package.json"&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;pkg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;json-parse-string&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring-no-properties&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-max&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;maphash&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;args&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;gethash&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="nv"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'args&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'args&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;prodigy-define-service&lt;/span&gt;
                        &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="ss"&gt;:command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;package-manager&lt;/span&gt; &lt;span class="s"&gt;"npm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="ss"&gt;:cwd&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-directory&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="ss"&gt;:path&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-directory&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="ss"&gt;:args&lt;/span&gt; &lt;span class="nv"&gt;args&lt;/span&gt;
                        &lt;span class="ss"&gt;:tags&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="ss"&gt;:stop-signal&lt;/span&gt; &lt;span class="ss"&gt;'sigkill&lt;/span&gt;
                        &lt;span class="ss"&gt;:kill-process-buffer-on-stop&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
                        &lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;gethash&lt;/span&gt; &lt;span class="s"&gt;"scripts"&lt;/span&gt; &lt;span class="nv"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;prodigy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;prodigy-refresh&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is defining a function called &lt;code&gt;my/create-prodigy-service&lt;/code&gt; that creates new prodigy services based on the contents of the current &lt;code&gt;package.json&lt;/code&gt; file.&lt;br&gt;
You can put this in your init.el file and call it from within Emacs.&lt;/p&gt;

&lt;p&gt;Here is a breakdown of the code:&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;(interactive)&lt;/code&gt; line is important if you plan to use the function interactively, meaning you can call it through a keybinding or by typing &lt;code&gt;M-x&lt;/code&gt; and the function name.&lt;/p&gt;

&lt;p&gt;In this line, the contents of the current buffer are parsed as a JSON string using the &lt;code&gt;json-parse-string&lt;/code&gt; function.&lt;br&gt;
The result is stored in a variable called &lt;code&gt;pkg&lt;/code&gt;. The &lt;code&gt;(point-min)&lt;/code&gt; and &lt;code&gt;(point-max)&lt;/code&gt; functions are used to get the positions of the first and last characters of the buffer, so that &lt;code&gt;buffer-substring-no-properties&lt;/code&gt; can extract the contents of the buffer as a string.&lt;/p&gt;

&lt;p&gt;Then we use the &lt;code&gt;maphash&lt;/code&gt; function to iterate over each key-value pair in the &lt;code&gt;"scripts"&lt;/code&gt; hash in the &lt;code&gt;pkg&lt;/code&gt; variable. The &lt;code&gt;gethash&lt;/code&gt; function is used to get the value associated with the &lt;code&gt;"scripts"&lt;/code&gt; key.&lt;/p&gt;

&lt;p&gt;And next we define an anonymous function that takes two arguments: &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt;. This function will be used as the mapping function for &lt;code&gt;maphash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside the mapping function, a new variable &lt;code&gt;args&lt;/code&gt; is initialized as an empty list. Another variable &lt;code&gt;name&lt;/code&gt; is assigned the value of the &lt;code&gt;"name"&lt;/code&gt; key in the &lt;code&gt;pkg&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Then we define a new prodigy service using the &lt;code&gt;prodigy-define-service&lt;/code&gt; function. The &lt;code&gt;:name&lt;/code&gt; parameter uses the &lt;code&gt;concat&lt;/code&gt; function to combine the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;key&lt;/code&gt; variables. The &lt;code&gt;:command&lt;/code&gt; parameter is set to "npm". The &lt;code&gt;:cwd&lt;/code&gt; and &lt;code&gt;:path&lt;/code&gt; parameters are set to the directory of the current buffer file. The &lt;code&gt;:args&lt;/code&gt; parameter is set to the &lt;code&gt;args&lt;/code&gt; list. The &lt;code&gt;:tags&lt;/code&gt; parameter is set to '(temp), indicating that the service is temporary. The &lt;code&gt;:stop-signal&lt;/code&gt; parameter is set to &lt;code&gt;sigkill&lt;/code&gt; to force-stop the service. The &lt;code&gt;:kill-process-buffer-on-stop&lt;/code&gt; parameter is set to &lt;code&gt;t&lt;/code&gt; to automatically kill the process buffer when the service is stopped.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;prodigy&lt;/code&gt; is called to start all defined prodigy services and then &lt;code&gt;prodigy-refresh&lt;/code&gt; to refresh the list of services.&lt;/p&gt;

&lt;p&gt;Overall, this code creates prodigy services for each script defined in the &lt;code&gt;"scripts"&lt;/code&gt; section of the &lt;code&gt;package.json&lt;/code&gt; file. It uses the name of the package as part of the service name, and sets the appropriate command, working directory, and arguments for each service.&lt;/p&gt;

&lt;p&gt;Here is how it works, open your package.json file situated in the project root folder.&lt;br&gt;
And invoke &lt;code&gt;M-x my/create-prodigy-service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to call inside a lisp file, you can define a function and call it using the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;my/create-prodigy-service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default it will use &lt;code&gt;npm&lt;/code&gt; as the default package manager, if you want to use any other package  manager, you can specify it as follows:&lt;/p&gt;

&lt;p&gt;For using yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;my/create-prodigy-service&lt;/span&gt; &lt;span class="s"&gt;"yarn"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For using pnpm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;my/create-prodigy-service&lt;/span&gt; &lt;span class="s"&gt;"pnpm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0bc1w2n0iyv0qtl6cxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0bc1w2n0iyv0qtl6cxr.png" alt="Image description" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the post, if you have any alternate approaches, feedback or queries, please let me know in the comments section.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>emacs</category>
      <category>programming</category>
    </item>
    <item>
      <title>5 ways to get text from an Emacs buffer</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Mon, 01 Jan 2024 10:33:39 +0000</pubDate>
      <link>https://forem.com/rajasegar/5-ways-to-get-text-from-an-emacs-buffer-4c3l</link>
      <guid>https://forem.com/rajasegar/5-ways-to-get-text-from-an-emacs-buffer-4c3l</guid>
      <description>&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eintr/" rel="noopener noreferrer"&gt;Emacs Lisp&lt;/a&gt; is a powerful programming language that allows you to customize and extend your Emacs editor. One common task when working with text in Emacs Lisp is extracting or copying text from a buffer. In this blog post, we will explore different ways of getting text from an Emacs buffer.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Using &lt;code&gt;buffer-substring&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;buffer-substring&lt;/code&gt; function is a simple and straightforward way to extract text from a buffer. It takes two arguments: start and end positions, and returns the corresponding text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-min&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;end&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-max&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring&lt;/span&gt; &lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="nv"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we extract the entire buffer by setting the start position to &lt;code&gt;(point-min)&lt;/code&gt; and the end position to &lt;code&gt;(point-max)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Using &lt;code&gt;buffer-substring-no-properties&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you want to exclude text properties (such as font face or color) from the extracted text, you can use the &lt;code&gt;buffer-substring-no-properties&lt;/code&gt; function. It works the same way as &lt;code&gt;buffer-substring&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-min&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;end&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-max&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring-no-properties&lt;/span&gt; &lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="nv"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Using &lt;code&gt;buffer-string&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;buffer-string&lt;/code&gt; function returns the entire contents of the current buffer as a string. This is a convenient way to extract text when you don't need to specify start and end positions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Using region
&lt;/h3&gt;

&lt;p&gt;If you have an active region in your Emacs buffer, you can use the &lt;code&gt;region-beginning&lt;/code&gt; and &lt;code&gt;region-end&lt;/code&gt; functions to get the start and end positions of the selected text. You can then use &lt;code&gt;buffer-substring&lt;/code&gt; or &lt;code&gt;buffer-substring-no-properties&lt;/code&gt; to extract the text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;region-beginning&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;end&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;region-end&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring&lt;/span&gt; &lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="nv"&gt;end&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Using &lt;code&gt;thing-at-point&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;thing-at-point&lt;/code&gt; function allows you to retrieve different types of text at the current point. You can specify the type of thing using the &lt;code&gt;thing&lt;/code&gt; argument. For example, to get the word at point, you can use &lt;code&gt;(thing-at-point 'word)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;thing-at-point&lt;/span&gt; &lt;span class="ss"&gt;'word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also combine &lt;code&gt;thing-at-point&lt;/code&gt; with &lt;code&gt;bounds-of-thing-at-point&lt;/code&gt; to retrieve the start and end positions of the thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;bounds&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;bounds-of-thing-at-point&lt;/span&gt; &lt;span class="ss"&gt;'word&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt; &lt;span class="nv"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr&lt;/span&gt; &lt;span class="nv"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are just a few examples of different ways to extract text from an Emacs buffer in Emacs Lisp. Depending on your specific use case, you may choose a different approach. Emacs Lisp provides a wide range of functions and tools to manipulate text, giving you the flexibility to perform various text-related operations in Emacs.&lt;/p&gt;

&lt;p&gt;If you know any other way of obtaining the text from the buffer, please let us know in the comments section. I would love to learn more tricks about Elisp functions for getting text from the buffer.&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>productivity</category>
      <category>lisp</category>
    </item>
    <item>
      <title>Debugging rules: Change one thing at a time</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Sat, 07 Oct 2023 13:33:31 +0000</pubDate>
      <link>https://forem.com/rajasegar/debugging-rules-change-one-thing-at-a-time-3kc6</link>
      <guid>https://forem.com/rajasegar/debugging-rules-change-one-thing-at-a-time-3kc6</guid>
      <description>&lt;p&gt;Altering elements individually poses its own set of challenges. When modifications occur in pairs, the potential arises for subtle errors that closely resemble the initial issues. This leaves you in a perplexing situation, unsure whether the correction wasn't applied, if the correction inadvertently introduced a similar problem, or if the original error persists along with a comparable new one. To navigate this complexity, adhere to simplicity: implement just one change at a time.&lt;/p&gt;

&lt;p&gt;Opt for a focused approach of making singular adjustments. Discard the notion of a shotgun strategy; instead, equip yourself with a precise rifle. This method proves more effective in resolving bugs, as indiscriminate alterations can disrupt otherwise functional components.&lt;/p&gt;

&lt;p&gt;Moreover, pinpointing the exact failure allows you to address only that specific issue. Essentially, if you believe a wide-ranging approach is necessary, the underlying problem likely lies in the lack of clarity regarding the target.&lt;/p&gt;

&lt;p&gt;In numerous instances, the inclination to modify various components within the system arises with the aim of assessing their impact on the issue at hand. However, this tendency often serves as a red flag, indicating a reliance on guesswork rather than leveraging instrumentation effectively to comprehend the underlying dynamics. Instead of diligently observing the natural occurrence of the failure, there's a shift towards altering conditions, potentially concealing the initial problem and potentially giving rise to additional issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's more effective to remember to do&lt;br&gt;
something than to remember not to do something.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Isolate the key factor
&lt;/h2&gt;

&lt;p&gt;The essence of effective debugging lies in pinpointing the critical factor by narrowing the focus to a specific section of code where a potential issue may be situated. This targeted approach empowers developers to efficiently recognize and address problems, leading to time and effort savings. By honing in on a particular segment, be it a function or module, the debugging process gains precision and effectiveness.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58z9pgapjv01zjwx0r8k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58z9pgapjv01zjwx0r8k.jpg" alt="Image description" width="600" height="702"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a robust technique to zero in on the suspicious region of the code, systematically eliminate portions of the program and observe if the error persists. If the issue disappears, it indicates that the problem lies in the removed part; if it persists, the problem resides in the retained portion.&lt;/p&gt;

&lt;p&gt;Consider whether this exhibits a familiar pattern. Recognizing the phrase "I've seen that before" often marks the inception of understanding, if not the complete solution. Common bugs tend to exhibit distinctive signatures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change one test at a time
&lt;/h2&gt;

&lt;p&gt;Occasionally, altering the test sequence or adjusting certain operational parameters can induce a problem to manifest more consistently, offering a clearer view of the failure and providing valuable insights into the underlying issues. Nevertheless, it remains crucial to adhere to the principle of modifying only one element at a time. This ensures precise identification of the parameter responsible for the observed effect. If a modification appears ineffective, promptly revert it to its original state.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0j1gke3l2ils9h7ym56i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0j1gke3l2ils9h7ym56i.jpg" alt="Image description" width="600" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare it with a good one
&lt;/h2&gt;

&lt;p&gt;Once you possess a method to induce a system to either fail or remain functional, even if the occurrence is sporadic, you find yourself in an excellent position to function as a differencing engine.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be a differencing engine! See the world! Or, at least, see the differences!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By examining two scenarios, one experiencing failure and the other functioning correctly, compare various aspects such as scope traces, code traces, debug output, and status windows or any other instrumented elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjfmqwjnuec97ejqxl9j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjfmqwjnuec97ejqxl9j.jpg" alt="Image description" width="600" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If a multitude of code changes occurred between the two tests or if distinct scenarios were set up, comparing the tests can become challenging. Constantly addressing differences unrelated to the bug might obscure the identification of the actual issue. It is essential to minimize disparities between the two traces to isolate the bug. Aim to obtain logs from the same machine during consecutive attempts, avoiding variations like different machines, software, parameters, user input, days, or environments.&lt;/p&gt;

&lt;p&gt;This doesn't imply that you shouldn't instrument elements unrelated to the bug. Since the relevance of certain aspects to the bug is not yet clear, comprehensive instrumentation is crucial. Even if an aspect is unrelated, it will manifest consistently in both logs, allowing you to swiftly bypass irrelevant data during analysis.&lt;/p&gt;

&lt;p&gt;Identifying problematic elements isn't a skill easily imparted to beginners or automatable through programming. What you seek is ever-changing and distinct from previous instances. Navigating through irrelevant disparities induced by timing or other factors requires a significant level of knowledge and intelligence. This level of understanding surpasses the capabilities of a novice, and the required discernment goes beyond the capabilities of software.&lt;/p&gt;

&lt;p&gt;When confronted with an extensive and intricate log, there may be a temptation to focus solely on suspect areas, which is acceptable if an issue is promptly discovered. However, in cases where no immediate revelation occurs, be prepared to examine the entire log, as the location of pertinent differences remains uncertain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the bad ones all have something that the good ones don't, you are onto the problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Examine the most recent change
&lt;/h2&gt;

&lt;p&gt;Identifying the most recent alteration is crucial. When adhering to the practice of modifying only one aspect at a time during the evolution of a program, the bug is likely either within the new code or brought to light by it. Scrutinizing recent changes is instrumental in localizing the issue. If the bug surfaces in the new version but not in the old one, it implicates the new code as part of the problem.&lt;/p&gt;

&lt;p&gt;At times, the distinction between a functional system and a malfunctioning one can be traced back to a design alteration. In such cases, a once-reliable system starts exhibiting failures. Pinpointing the version that initially triggers the failure, even if it entails testing progressively older versions until the issue dissipates, is beneficial. Once the problem disappears, progress to the subsequent version and confirm the recurrence of the failure. This process effectively narrows down the problem to alterations between those two versions, providing a focused perspective on the issue, assuming the change wasn't a complete overhaul of the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnxlzz74wqmrtu3t9jut.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnxlzz74wqmrtu3t9jut.jpg" alt="Image description" width="612" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typically, new designs undergo testing before being shipped due to the common occurrence of faults in their initial iterations. Compatibility issues often arise when a new design in one section does not align well with another section that was functioning perfectly.&lt;/p&gt;

&lt;p&gt;However, some cases prove challenging. Occasionally, a longstanding issue only manifests itself when other changes occur. The introduction of new code or a hardware revision may create conditions causing a previously reliable subsystem to fail. It's akin to discovering a hole in the subsystem that was always there, but you never ventured close enough to fall through it before. While fixing the immediate bug leading to the hole might be tempting and sometimes necessary for short-term solutions, the ultimate goal is to address and seal the underlying issue.&lt;/p&gt;

&lt;p&gt;When confronted with a perplexing new error, the root cause is often linked to recently altered code, whether it's entirely new or modifications to existing code. If unable to identify a defect, running an older version of the program can help determine whether the error persists. If it doesn't, it indicates that the error lies in the new version or stems from an interaction with the changes made in the new version.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Scrutinize the differences between the old and new versions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examine the version control log to identify recent code modifications. If this is not feasible, employ a differential tool to compare alterations between the previous functional source code and the current malfunctioning source code.&lt;/p&gt;

&lt;p&gt;Seeking predictability in your routine is essential. Eliminate modifications that did not yield the anticipated results, as they likely introduced unexpected consequences.&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>productivity</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>Ember Language Server in Emacs</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Thu, 05 Oct 2023 04:13:45 +0000</pubDate>
      <link>https://forem.com/rajasegar/ember-language-server-in-emacs-2972</link>
      <guid>https://forem.com/rajasegar/ember-language-server-in-emacs-2972</guid>
      <description>&lt;p&gt;In this post we are going to see how we can set up the language server for Ember in Emacs.&lt;/p&gt;

&lt;p&gt;A language server is a program that provides language-specific features for code editors or integrated development environments (IDEs). It acts as a server, interacting with the editor to offer services such as code completion, error checking, and other language-specific features. In summary, language servers enhance the development experience by providing consistent language support, intelligent features, and improved productivity across various code editors and IDEs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ember.js
&lt;/h2&gt;

&lt;p&gt;Ember.js stands out as a robust and proven JavaScript framework designed to facilitate the development of contemporary web applications. Equipped with comprehensive tools, it empowers developers to create feature-rich user interfaces that seamlessly function across various devices. Widely recognized as a framework tailored for ambitious web developers, Ember.js offers a productive environment for building sophisticated web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emacs
&lt;/h2&gt;

&lt;p&gt;GNU Emacs stands as a freely available text editor crafted by Richard Stallman, the founder of the GNU Project. Originating from the Emacs editor designed for Unix operating systems, GNU Emacs has played a pivotal role in the GNU project and serves as a flagship initiative within the free software movement. Its defining characteristic is encapsulated in the tagline "the extensible self-documenting text editor."&lt;/p&gt;

&lt;h2&gt;
  
  
  Ember Language Server
&lt;/h2&gt;

&lt;p&gt;The Ember Language Server (ELS) implements the Language Server Protocol for Ember.js projects. ELS enables editors to provide features like auto complete, goto definition and diagnostics. To get these features, you have to install the plugin for your editor.&lt;/p&gt;

&lt;p&gt;For this post we are going to use a particular version of ELS created by &lt;a href="https://github.com/lifeart" rel="noopener noreferrer"&gt;Alex Kanunnikov&lt;/a&gt;. You can find the code here in &lt;a href="https://github.com/lifeart/ember-language-server" rel="noopener noreferrer"&gt;ember-language-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to clone this in your local machine and build it. Then we use the build artifacts to start the language server automatically from Emacs using the LSP tooling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/lifeart/ember-language-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also another version of language server provided by the official Ember community which you can found &lt;a href="https://github.com/ember-tooling/ember-language-server" rel="noopener noreferrer"&gt;ember-tooling/ember-language-server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  emacs-lsp-mode
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://emacs-lsp.github.io/lsp-mode/" rel="noopener noreferrer"&gt;lsp-mode&lt;/a&gt; package provides the Language Server Protocol support for Emacs. It is community driven, fully featured, performant, flexible and easy to configure. It supports all features in Language Server Protocol v3.14. You can choose between full-blown IDE with flashy UI or minimal distraction free. It just works out of the box and automatically upgrades if additional packages are present.&lt;/p&gt;

&lt;p&gt;Before configuring the lsp-mode for Ember we need to define a new major mode called &lt;code&gt;hbs-mode&lt;/code&gt; for editing Handlebars templates. Here's how we do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-derived-mode&lt;/span&gt; &lt;span class="nv"&gt;hbs-mode&lt;/span&gt; &lt;span class="nv"&gt;web-mode&lt;/span&gt; &lt;span class="s"&gt;"Handlebars mode"&lt;/span&gt; &lt;span class="s"&gt;"Major mode for handlebars"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'auto-mode-alist&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\.hbs\\'"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;hbs-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code we are defining a new major mode named &lt;code&gt;hbs-mode&lt;/code&gt; by deriving it from the existing mode &lt;code&gt;web-mode&lt;/code&gt;. The string "Handlebars mode" is the mode's user-friendly name, and "Major mode for handlebars" is its documentation string. In Emacs, major modes are used to provide specialized editing features for specific types of files. In this case, &lt;code&gt;hbs-mode&lt;/code&gt; is specifically tailored for editing Handlebars templates.&lt;/p&gt;

&lt;p&gt;Next we add an entry to the &lt;code&gt;auto-mode-alist&lt;/code&gt; variable, which is a list of filename patterns and corresponding major modes. When you open a file, Emacs checks this list to determine which major mode to use based on the file's extension. The added entry specifies that any file with the extension ".hbs" should be opened in &lt;code&gt;hbs-mode&lt;/code&gt;. The regular expression "\\ .hbs\\'" is used to match file names ending with ".hbs".&lt;/p&gt;

&lt;p&gt;The dot (&lt;code&gt;.&lt;/code&gt;) in the regular expression is a wildcard that matches any character, and the double backslash (&lt;code&gt;\\&lt;/code&gt;) is used to escape the dot and match it literally. The single-quote (&lt;code&gt;'&lt;/code&gt;) in the regular expression matches the end of the string.&lt;/p&gt;

&lt;p&gt;In short, this code sets up a new major mode called &lt;code&gt;hbs-mode&lt;/code&gt; for editing Handlebars templates in Emacs. It also ensures that any file with the extension ".hbs" will automatically use this major mode when opened in Emacs.&lt;/p&gt;

&lt;p&gt;You need to add the following code to your Emacs configuration file to get the language server working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with-eval-after-load&lt;/span&gt; &lt;span class="ss"&gt;'lsp-mode&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'lsp-language-id-configuration&lt;/span&gt;
       &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;hbs-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"hbs"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-register-client&lt;/span&gt;
      &lt;span class="c1"&gt;;; Git clone language server from https://github.com/lifeart/ember-language-server/tree/component-context-info-origin&lt;/span&gt;
      &lt;span class="c1"&gt;;; And build it&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-lsp-client&lt;/span&gt; &lt;span class="ss"&gt;:new-connection&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-stdio-connection&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="s"&gt;"node"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expand-file-name&lt;/span&gt; &lt;span class="s"&gt;"~/www/ember-language-server/lib/start-server.js"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"--stdio"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="ss"&gt;:activation-fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-activate-on&lt;/span&gt; &lt;span class="s"&gt;"hbs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="ss"&gt;:server-id&lt;/span&gt; &lt;span class="ss"&gt;'ember-language-server&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain what the above code does.&lt;/p&gt;

&lt;p&gt;The macro &lt;code&gt;(with-eval-after-load 'lsp-mode )&lt;/code&gt; ensures that the enclosed code is executed after the &lt;code&gt;lsp-mode&lt;/code&gt; package has been loaded. It is used to set up configurations or additional actions related to the &lt;code&gt;lsp-mode&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;The line &lt;code&gt;(add-to-list 'lsp-language-id-configuration &amp;amp;#x2026;)&lt;/code&gt; adds an entry to the &lt;code&gt;lsp-language-id-configuration&lt;/code&gt; variable, which is used to configure language identifiers for the Language Server Protocol (LSP). In this case, it associates the language identifier &lt;code&gt;'hbs-mode'&lt;/code&gt; with the string &lt;code&gt;"hbs"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The function call &lt;code&gt;(lsp-register-client &amp;amp;#x2026;)&lt;/code&gt; registers a new LSP client for handling the Ember Language Server. The &lt;code&gt;:new-connection&lt;/code&gt; property specifies how to establish a connection to the language server. Here, it uses &lt;code&gt;lsp-stdio-connection&lt;/code&gt; with a list of arguments. It's starting the server using Node.js and pointing to the &lt;code&gt;start-server.js&lt;/code&gt; file of the Ember Language Server. The &lt;code&gt;:activation-fn&lt;/code&gt; property specifies when to activate the language server. It uses &lt;code&gt;lsp-activate-on&lt;/code&gt; with the argument &lt;code&gt;"hbs"&lt;/code&gt;, meaning the server should be activated when working with files of type &lt;code&gt;"hbs"&lt;/code&gt;. The &lt;code&gt;:server-id&lt;/code&gt; property  associates a unique identifier with this server configuration. In this case, it's set to &lt;code&gt;'ember-language-server'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In summary, this code is configuring Emacs to use the Ember Language Server for Handlebars files (&lt;code&gt;hbs-mode&lt;/code&gt;). The language server is started as a new process using Node.js, and it will be activated whenever a Handlebars file is being edited. The server configuration is registered with the identifier &lt;code&gt;'ember-language-server'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So this is the final and full code for configuring lsp-mode for Ember handlebars in Emacs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-derived-mode&lt;/span&gt; &lt;span class="nv"&gt;hbs-mode&lt;/span&gt; &lt;span class="nv"&gt;web-mode&lt;/span&gt; &lt;span class="s"&gt;"Handlebars mode"&lt;/span&gt; &lt;span class="s"&gt;"Major mode for handlebars"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'auto-mode-alist&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\.hbs\\'"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;hbs-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with-eval-after-load&lt;/span&gt; &lt;span class="ss"&gt;'lsp-mode&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'lsp-language-id-configuration&lt;/span&gt;
        &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;hbs-mode&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"hbs"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-register-client&lt;/span&gt;
    &lt;span class="c1"&gt;;; Git clone language server from https://github.com/lifeart/ember-language-server/tree/component-context-info-origin&lt;/span&gt;
    &lt;span class="c1"&gt;;; And build it&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-lsp-client&lt;/span&gt; &lt;span class="ss"&gt;:new-connection&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-stdio-connection&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="s"&gt;"node"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expand-file-name&lt;/span&gt; &lt;span class="s"&gt;"~/www/ember-language-server/lib/start-server.js"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"--stdio"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="ss"&gt;:activation-fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lsp-activate-on&lt;/span&gt; &lt;span class="s"&gt;"hbs"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="ss"&gt;:server-id&lt;/span&gt; &lt;span class="ss"&gt;'ember-language-server&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  eglot
&lt;/h2&gt;

&lt;p&gt;Next we try to achieve the same with another LSP tool in Emacs called &lt;a href="https://joaotavora.github.io/eglot/" rel="noopener noreferrer"&gt;eglot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eglot is the Emacs client for the Language Server Protocol (LSP). The name “Eglot” is an acronym that stands for “Emacs Polyglot”. Eglot provides infrastructure and a set of commands for enriching the source code editing capabilities of Emacs via LSP. Eglot itself is completely language-agnostic, but it can support any programming language for which there is a language server and an Emacs major mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    (add-hook 'hbs-mode-hook 'eglot-ensure)
    (with-eval-after-load 'eglot
      (add-to-list 'eglot-server-programs
                   '(hbs-mode . ("node" "/Users/rajasegarchandran/www/ember-language-server/lib/start-server.js" "--stdio"))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down the code:&lt;/p&gt;

&lt;p&gt;First we add a function (&lt;code&gt;eglot-ensure&lt;/code&gt;) to the &lt;code&gt;hbs-mode-hook&lt;/code&gt;. In Emacs, a "hook" is a way to run custom code when a certain mode is activated.In this case, it ensures that the eglot server is started when &lt;code&gt;hbs-mode&lt;/code&gt; is activated.&lt;/p&gt;

&lt;p&gt;Now we delay the execution of the code inside it until after the &lt;code&gt;eglot&lt;/code&gt; package has been loaded. This is useful because it ensures that the configuration is applied after the &lt;code&gt;eglot&lt;/code&gt; package is available. Next we add an entry to the &lt;code&gt;eglot-server-programs&lt;/code&gt; list, which specifies the command to start the language server for a particular mode. Then we associate the &lt;code&gt;hbs-mode&lt;/code&gt; with the command to start the Ember Language Server for Handlebars. The server is started using the "node" executable, and it runs the specified JavaScript file (&lt;code&gt;start-server.js&lt;/code&gt;) with the "--stdio" option.&lt;/p&gt;

&lt;p&gt;The command &lt;code&gt;node&lt;/code&gt; and its arguments that will be executed when the language server for Handlebars is started.&lt;br&gt;
It launches the Node.js interpreter with the specified JavaScript file and tells it to use the standard I/O for communication.&lt;/p&gt;

&lt;p&gt;We basically ensure that the eglot server is started automatically when &lt;code&gt;hbs-mode&lt;/code&gt; is activated, and it specifies the command to start the language server for Handlebars.&lt;/p&gt;

&lt;p&gt;Now you know how to configure and register the Ember Language Server for handling Handlebars (hbs) files within the Emacs text editor.&lt;/p&gt;

</description>
      <category>ember</category>
      <category>emacs</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Debugging rules: Quit thinking and look</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Sat, 09 Sep 2023 04:05:43 +0000</pubDate>
      <link>https://forem.com/rajasegar/debugging-rules-quit-thinking-and-look-3ang</link>
      <guid>https://forem.com/rajasegar/debugging-rules-quit-thinking-and-look-3ang</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It is a capital mistake to theorize before one has data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Observing the failure firsthand is essential. When you make assumptions about the problem's cause, you often end up trying to fix something unrelated to the actual bug. This not only results in an ineffective solution but also consumes valuable time and resources, possibly causing additional issues. Avoid this approach.&lt;/p&gt;

&lt;p&gt;Instead, stop overthinking and start observing. This is among the most valuable advice you can give to anyone dealing with debugging.&lt;/p&gt;

&lt;p&gt;Engineers are inherently analytical thinkers. They enjoy the intellectual challenge, which is why they chose engineering over physical labor. While engineers generate ingenious ideas, there are more ways for things to go wrong than even the most imaginative engineer can anticipate. So, why do we believe we can solve problems purely through thought? Because we are engineers, and thinking is more convenient than observing.&lt;/p&gt;

&lt;p&gt;Observing is demanding. It is often, if not always, more complex than we would prefer. In the realm of software, observing entails setting breakpoints, inserting debug statements, monitoring program variables, and inspecting memory.&lt;/p&gt;

&lt;p&gt;After you have dis-proven your initial assumptions, you are still left with the task of identifying the bug. You end up with the same workload as before, but now you have less time. This is far from ideal unless you subscribe to the notion that the sooner you fall behind, the more time you have to catch up. Therefore, here are some guidelines to help you prioritize observation over premature speculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  See the failure
&lt;/h2&gt;

&lt;p&gt;It appears self-evident that to identify a failure, one must witness the failure occurring firsthand. When we observe a bug, what we are actually seeing is the aftermath of the failure. To effectively debug, it is imperative to scrutinize the failure in intricate detail. Many issues can be easily misconstrued if you cannot observe the entire sequence of events as they unfold. Without a comprehensive view, you may inadvertently address a problem you've merely speculated about, when in reality, a completely different element has malfunctioned. The true nature of the problem becomes evident only when someone observes it in action.&lt;/p&gt;

&lt;p&gt;Ensure that you have a clear understanding of the precise issue at hand. In most cases, the act of observation is significantly faster than relying on hasty guesswork shortcuts, as these shortcuts often lead to dead ends.&lt;/p&gt;

&lt;h2&gt;
  
  
  See the details
&lt;/h2&gt;

&lt;p&gt;The extent of observation needed is usually quite limited. In most cases, with each instance of examining the system to observe the failure, you gain additional insights into the nature of the malfunction. This enables you to determine where to delve deeper to acquire more detailed information. Gradually, you accumulate sufficient details to justify an examination of the system's design, aiming to pinpoint the root cause of the issue.&lt;/p&gt;

&lt;p&gt;When should you transition from observation to analysis? Continue the process of observation until the visible failure narrows down to a manageable number of potential causes that warrant further examination.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Streetlight effect
&lt;/h3&gt;

&lt;p&gt;There's something called "The Streetlight effect". It's a metaphor for knowledge and ignorance. The streetlight effect, or the drunkard's search principle, is a type of observational bias that occurs when people only search for something where it is easiest to look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiuneqt0pciterkrxijt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsiuneqt0pciterkrxijt.jpg" alt="Image description" width="563" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build instrumentation in
&lt;/h2&gt;

&lt;p&gt;In the realm of software development, the initial layer of built-in instrumentation typically involves compiling the code in debug mode, enabling you to observe the program's execution using a source code debugger.&lt;/p&gt;

&lt;p&gt;Having a higher volume of status messages is beneficial, but it's essential to incorporate a mechanism that allows you to selectively enable or disable specific messages or message types. This flexibility enables you to focus your attention on the messages relevant to diagnosing a particular issue.&lt;/p&gt;

&lt;p&gt;It's crucial to incorporate debugging considerations right from the outset of the design process. Ensure that instrumentation is a fundamental component of your product requirements. Incorporate hooks for instrumentation in every functional specification and API definition. Include the debug monitor and analysis filter as integral components of your standard utility toolkit.&lt;/p&gt;

&lt;p&gt;Furthermore, aside from simplifying the eventual debugging process, contemplating the instrumentation needs also aids in designing the system more effectively and mitigating some of the potential bugs from arising in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add instrumentation on
&lt;/h2&gt;

&lt;p&gt;If you weren't able to incorporate instrumentation during the initial development, at the very least, consider adding it afterward. Utilize a debugger to gain an internal perspective on your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't be afraid to dive in
&lt;/h2&gt;

&lt;p&gt;If a bug is present in the code, you'll eventually need to recompile the software to rectify it. Consequently, you should also be open to recompiling the software to initially identify the bug. Create a debug version that allows you to access the source code and incorporate new debugging statements to inspect the crucial parameters you need to examine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch out for Heisenbugs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Werner_Heisenberg" rel="noopener noreferrer"&gt;Heisenberg&lt;/a&gt; emerged as one of the trailblazers in the field of quantum physics. While delving into the intricate world of extremely light and minuscule atomic particles, he recognized a fundamental principle: when dealing with these particles, you can either measure their precise location or their trajectory, but the more accurately you determine one of these aspects, the more you perturb the other.&lt;/p&gt;

&lt;p&gt;A HeisenBug is a glitch that exhibits a peculiar characteristic—it responds to the act of observation. For instance, it might mysteriously vanish when the program is in debug mode. &lt;/p&gt;

&lt;p&gt;The challenge arises from the fact that obtaining an accurate measurement is hindered because the tools used for observation are an integral part of the system. Your testing instruments inherently impact the system undergoing examination.&lt;/p&gt;

&lt;p&gt;Even a debugger can introduce some degree of timing variation, and any form of instrumentation, to varying extents, influences the system's behavior. This is an unavoidable reality, and it's crucial to bear this in mind so that you're not caught off guard by these effects. Additionally, some methods of instrumentation are less intrusive than others.&lt;/p&gt;

&lt;p&gt;Remarkably, even minor alterations can perturb the system enough to obscure the bug entirely. Instrumentation is one such alteration. Therefore, after implementing instrumentation in a malfunctioning system, it's imperative to recreate the failure to ascertain that Heisenberg's principle is not inadvertently confounding your efforts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guess only to focus the search
&lt;/h2&gt;

&lt;p&gt;Guessing can be a valuable tool, particularly when you have a strong grasp of the system. Your educated guesses might even come close to the mark. However, it's crucial to use guesswork as a means to narrow down your search. You must still validate your assumptions by witnessing the failure before attempting to rectify it.&lt;/p&gt;

&lt;p&gt;When you encounter an unexpected bug, it's essential to reevaluate the certainties you hold dear. The degree of surprise you experience when something goes awry is directly linked to the level of trust and confidence you place in the code that's running. Therefore, when confronted with an "astonishing" failure, it's imperative to recognize that one or more of your foundational assumptions are incorrect.&lt;/p&gt;

&lt;p&gt;In the face of an unforeseen bug, your task extends beyond mere resolution; you must also investigate why this issue went unnoticed until now. Ensure that whatever transpired, you have mechanisms in place to detect it if it occurs again.&lt;/p&gt;

&lt;p&gt;Furthermore, if the bug stems from misconceptions held by a team member, it's essential to engage in a collective discussion about the problem. If one person misunderstands, it's possible that others share the same misconception.&lt;/p&gt;

&lt;p&gt;Hence, it's advisable not to place excessive trust in your initial guesses; often, they can lead you down the wrong path and prove to be significantly off the mark. If meticulous instrumentation fails to corroborate a particular assumption, it's time to step back and reconsider your guesswork.&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>productivity</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>Debugging Rules: Keep an Audit Trail</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Sat, 19 Aug 2023 04:50:46 +0000</pubDate>
      <link>https://forem.com/rajasegar/debugging-rules-keep-an-audit-trail-3he9</link>
      <guid>https://forem.com/rajasegar/debugging-rules-keep-an-audit-trail-3he9</guid>
      <description>&lt;p&gt;Debugging proves to be a challenging task that often demands extended and uncertain periods for resolution. Thus, the objective revolves around minimizing the necessity for extensive debugging. Skillful programmers acknowledge that they invest an equal amount of time in debugging as they do in actual coding, prompting them to extract lessons from their errors. Each identified bug serves as an opportunity to grasp methods for averting analogous issues in the future or swiftly identifying them if they arise once more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"There is no branch of detective science which is so important and so much neglected as the art of tracing footsteps"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Occasionally, the seemingly trivial aspects can hold the essential clue to triggering a bug. Elements that appear unimportant to the QA person could hold significance for the troubleshooter. Likewise, what appears evident to the QA person might elude the person attempting the fix. Therefore, meticulous attention to every detail is crucial, as there's a possibility that seemingly insignificant factors could carry hidden importance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5lnxd9frml28wtblg2c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5lnxd9frml28wtblg2c.jpg" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Write down what you did, in what order, and what happened
&lt;/h2&gt;

&lt;p&gt;Maintain a record of actions taken. While delving into an issue, document your procedures, their sequential arrangement, and the ensuing outcomes. Consistently adhere to this practice. Think of it as akin to embedding instruments within the software or hardware - here, you're incorporating instrumentation into the testing process. This approach enables you to discern each undertaken step and its corresponding outcome. Such meticulous tracking aids in pinpointing the precise step deserving of attention during the debugging phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Devil is in the Details
&lt;/h2&gt;

&lt;p&gt;Recognize that every detail possesses potential significance. Regrettably, although the worth of maintaining an audit trail is commonly acknowledged, the extent of required specificity often isn't, leading to the omission of critical information. What type of system was in operation? How did the sequence of events unfold prior to the malfunction? And occasionally, what precisely constituted the failure itself?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrcgs10s1yplzrmkceju.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrcgs10s1yplzrmkceju.jpg" alt="Image description" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The essence lies in augmenting any debug traces or logs with supplementary conditions and symptoms that might not be explicitly present in the logs. If you can establish correlations between symptoms and timestamps, the efficacy is enhanced further.&lt;/p&gt;

&lt;p&gt;Maintain a precise and uniform approach when articulating descriptions. You can't commence the process of problem-solving until you have a firm grasp on the fundamental symptoms. Another noteworthy aspect is not solely comprehending what transpired, but also quantifying the extent of the occurrence. The pivotal element resided within a detail that one would typically overlook. Yet, a disposition to scrutinize and meticulously document every aspect is imperative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Correlate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mlj3ez377rid0sz5cu6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mlj3ez377rid0sz5cu6.jpeg" alt="Image description" width="270" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drawing connections between symptoms and other symptoms or debug data proves highly advantageous. In systems characterized by intercommunication among multiple devices, maintaining records for both systems, complete with accurately synchronized timestamps, holds significant value. This reservoir of information is tremendously beneficial. Numerous bugs have been unearthed through the process of correlating symptoms with human timelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit Trails for Design are also Good for Testing
&lt;/h2&gt;

&lt;p&gt;Exerting control over tools is paramount for precisely reproducing a version, and ensuring its presence is imperative. Unidentified deviations in tools can result in exceedingly peculiar outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shortest Pencil is longer than the longest memory
&lt;/h2&gt;

&lt;p&gt;Relying on your memory for specifics is inadvisable; instead, document them in writing. Placing trust solely in your memory leads to several eventualities. You'll inevitably overlook the details that seemed inconsequential in the moment, which ironically turn out to be pivotal. &lt;/p&gt;

&lt;p&gt;Additionally, you'll omit details that might not have held significance for you but could hold importance for others tackling different issues later on. This approach limits your ability to effectively convey information unless done verbally, causing unnecessary time wastage for everyone, assuming you're present to discuss it. Furthermore, retaining a comprehensive recollection of events, their sequence, and their interrelationships becomes an intricate challenge. This information, however, is fundamental.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qcrrpjog7bic3a6by7a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qcrrpjog7bic3a6by7a.jpg" alt="Image description" width="540" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Document the details by putting them in writing. Opt for digital documentation in a simple and easy to consume format to facilitate the creation of backup copies, seamless attachment to bug reports, effortless distribution to others, and the potential for subsequent analysis through automated tools. Jot down your actions and their corresponding outcomes. Preserve your debug logs and traces, and supplement them with contextual incidents and impacts that might not be explicitly captured. Record your hypotheses and solutions. Leave no aspect undocumented.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write it down. No matter how horrible the moment , make a memorandum of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Keep a notepad by your desk
&lt;/h2&gt;

&lt;p&gt;One factor leading programmers into a quandary during debugging sessions is delving excessively into fruitless routes. Compile a roster of strategies to attempt, and if a particular method proves ineffective, transition to the subsequent alternative.&lt;/p&gt;

&lt;p&gt;Maintaining an audit trail during debugging offers several key advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comprehensive Tracking:&lt;/strong&gt; An audit trail chronicles your investigative steps, enabling you to retrace your actions and decisions. This tracking ensures transparency and accountability in the debugging process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficient Collaboration:&lt;/strong&gt; Sharing an audit trail with colleagues or teammates enhances collaboration. Others can comprehend your thought process, aiding in quicker problem resolution and minimizing duplicated efforts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accurate Reproduction:&lt;/strong&gt; An audit trail facilitates the recreation of issues in controlled environments. By following the documented steps, you increase the likelihood of replicating the problem accurately, leading to more effective troubleshooting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Diagnosing Root Causes:&lt;/strong&gt; Analyzing the audit trail helps you pinpoint the exact moment or sequence of events that triggered the bug. This insight is invaluable in identifying underlying issues and formulating precise solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Holistic Understanding:&lt;/strong&gt; The trail captures not only the immediate actions but also the context and environmental conditions. This comprehensive understanding is crucial for grasping the bigger picture of the problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning and Improvement:&lt;/strong&gt; Reviewing past audit trails enables you to learn from previous experiences. Understanding the path taken to identify and rectify issues can help you avoid similar pitfalls in the future.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adaptable Problem-Solving:&lt;/strong&gt; With an audit trail, you can easily switch between different approaches without losing your progress. If one avenue proves unsuccessful, you can retrace your steps and pursue alternate solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Effective Documentation:&lt;/strong&gt; The audit trail serves as documentation of your debugging efforts. This documentation can be used for future reference, training new team members, and building a knowledge base.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimized Time Management:&lt;/strong&gt; Instead of aimlessly retracing your steps, you can refer to the audit trail to quickly resume your investigation. This prevents wasted time and expedites the resolution process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data-Driven Insights:&lt;/strong&gt; By recording observations, hypotheses, and results, you're gathering data that can provide insights into recurring issues, patterns, and potential improvements in the development process.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In summary, maintaining an audit trail during debugging promotes transparency, collaboration, and systematic analysis. It's an indispensable practice that enhances problem-solving efficiency and contributes to overall software quality.&lt;/p&gt;

&lt;p&gt;If the process of hunting for a bug continues for an extended period, you'll find it challenging to keep a clear record of your attempted solutions and the insights you've gained. By documenting your testing procedures and outcomes, the chances of missing crucial details or mistakenly assuming you've explored a certain avenue diminish. The act of jotting down your thoughts will enhance your recall of the issue when facing a similar situation in the future, and it will also be valuable when articulating the problem to another person.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Debugging Rules: Make it Fail</title>
      <dc:creator>Rajasegar Chandran</dc:creator>
      <pubDate>Tue, 15 Aug 2023 05:54:01 +0000</pubDate>
      <link>https://forem.com/rajasegar/debugging-rules-make-it-fail-33c0</link>
      <guid>https://forem.com/rajasegar/debugging-rules-make-it-fail-33c0</guid>
      <description>&lt;p&gt;This post is third in the series of posts about the rules of debugging.&lt;/p&gt;

&lt;p&gt;Adopting a methodical strategy for identifying and rectifying errors is essential for achieving success. The initial and primary phase of this approach involves achieving consistency in the failure. Direct your debugging efforts to ensure that each test conducted propels you incrementally closer to a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scientific Method of Debugging
&lt;/h2&gt;

&lt;p&gt;In his seminal book, Code Complete, Steve McConnell, simply draws parallels in debugging based on the Scientific Method, which is the process of discovery and demonstration necessary for scientific investigation.&lt;/p&gt;

&lt;p&gt;Based on the Scientific approach, an effective debugging approach would consist of the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stabilize the error&lt;/li&gt;
&lt;li&gt;Locate the source of the error&lt;/li&gt;
&lt;li&gt;Fix the defect&lt;/li&gt;
&lt;li&gt;Test the fix&lt;/li&gt;
&lt;li&gt;Look for similar errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9f552ob4gnmy9ghgymw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9f552ob4gnmy9ghgymw.jpg" alt="Image description" width="666" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the initial phase hinges on achieving repeatability. Diagnosing a defect becomes more manageable when it can be stabilized, ensuring consistent and reliable occurrence. Diagnosing a defect that lacks reliability in its occurrence becomes a formidable challenge. Establishing predictability for an intermittent defect ranks among the most demanding endeavors in the debugging process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stabilize the Error&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An error that manifests unpredictably is typically rooted in either initialization discrepancies or timing irregularities. The process of stabilizing such an error encompasses more than merely identifying a test case that triggers the error. It entails refining the test case to its simplest form while still yielding the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 reasons so you can
&lt;/h2&gt;

&lt;p&gt;There are three primary reasons why you are trying to make it fail consistently:&lt;/p&gt;

&lt;h3&gt;
  
  
  Look at it
&lt;/h3&gt;

&lt;p&gt;In order to see it fail, you have to be able to make it fail. You have to make it fail as regularly as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focus on the cause
&lt;/h3&gt;

&lt;p&gt;Knowing under exactly what conditions it will fail helps you focus on probable causes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tell if you've fixed it
&lt;/h3&gt;

&lt;p&gt;Once you think that you've fixed the problem having a surefire way to make it fail gives you a surefire test of whether you fixed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just Do it "again"
&lt;/h2&gt;

&lt;p&gt;However, how can you induce a failure? Well, a straightforward approach involves utilizing the system under normal conditions and observing instances of incorrect behavior. Naturally, this process aligns with the concept of testing; however, the crucial aspect lies in the ability to reproduce the failure repeatedly, extending beyond the initial occurrence. While a comprehensively documented testing procedure offers advantages, the primary focus should revolve around maintaining the mindset that a solitary failure is insufficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45sg4bueaw9zvwi8nnqv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45sg4bueaw9zvwi8nnqv.gif" alt="Image description" width="220" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examine your actions and replicate them deliberately. Record each action as you proceed. Subsequently, adhere to your documented procedure to verify its consistent capacity to trigger the error. Nonetheless, certain scenarios exist where orchestrating failure could result in harm or undesirable consequences. In such instances, perpetuating the same mode of failure consistently might not be prudent. Adjustments must be made to minimize the extent of potential damage, while striving to retain the essence of the original system and sequence to the greatest extent possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start at the beginning
&lt;/h2&gt;

&lt;p&gt;Frequently, the necessary actions are concise and minimal. On occasion, the order of events might be uncomplicated, yet a substantial amount of preparatory work is essential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8udm8xt2f218dvxoz1m.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8udm8xt2f218dvxoz1m.jpeg" alt="Image description" width="304" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bugs can depend on a complex state of the machine&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Due to the potential for bugs to rely on intricate machine states, it is imperative to meticulously observe and document the machine's state before initiating your sequence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stimulate the failure
&lt;/h2&gt;

&lt;p&gt;If the failure sequence involves numerous manual actions, streamlining the process through automation can prove advantageous.&lt;/p&gt;

&lt;p&gt;In numerous instances, the failure manifests itself only after a significant number of iterations, making it beneficial to employ an automated testing mechanism throughout the night. &lt;/p&gt;

&lt;h2&gt;
  
  
  Simulating vs Stimulating
&lt;/h2&gt;

&lt;p&gt;Distinguishing between inducing failure (good) and duplicating failure artificially (good) is crucial. It is acceptable to replicate the circumstances that lead to failure, but it's advisable to steer clear of artificially reproducing the failure mechanism itself.&lt;/p&gt;

&lt;p&gt;In instances involving intermittent bugs, you might speculate that a specific underlying mechanism is responsible for the failure. In response, you could construct a configuration that exercises this mechanism and subsequently observe a higher frequency of failures. Alternatively, if you encounter a bug discovered at a remote location, you might attempt to establish a comparable system in your own environment. In either scenario, your objective is to simulate the failure – essentially, to recreate it – albeit through an alternate approach or on a distinct system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't simulate the failure&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When attempting to deduce the failure mechanism, simulations frequently prove ineffective. This is typically due to either an inaccurate assumption or the alteration of conditions during testing. As a result, your simulated setup might exhibit consistent flawless performance or, more problematically, encounter a fresh failure mode that diverts your attention from the original bug you were initially investigating.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You have enough bugs already; don't try to create new ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're already dealing with a sufficient number of bugs; there's no need to intentionally introduce new ones. Utilize instrumentation to examine the source of the issue, but refrain from altering the underlying mechanism as it is the very cause of the failure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nmyb08kmuzkyc8c6nkk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nmyb08kmuzkyc8c6nkk.jpg" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Attempting to replicate a bug by inducing it on a similar system can be beneficial, but within certain boundaries. If a bug can be reproduced on multiple systems, it signifies a design flaw rather than an isolated system malfunction. Recreating the issue on specific configurations while excluding others aids in narrowing down potential root causes. However, if you encounter difficulty in swiftly reproducing the bug, avoid modifying your simulation to force its occurrence. Doing so would result in generating new configurations rather than examining a copy of the one that failed. &lt;/p&gt;

&lt;p&gt;When dealing with a system that experiences regular or intermittent failures, focus your efforts on addressing the problem within that specific system and configuration.&lt;/p&gt;

&lt;p&gt;Remember, this does not imply that you should avoid automating or intensifying your testing to trigger the failure. Automation can expedite the occurrence of intermittent issues, while intensification can make subtle problems more evident. Both methods contribute to provoking the failure without artificially simulating the malfunctioning mechanism. Any adjustments made should operate at a higher level, not altering how the system fails, but rather influencing its frequency. However, exercise caution to prevent excessive modifications that could potentially introduce new complications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Uncontrolled condition
&lt;/h2&gt;

&lt;p&gt;Identify the sporadic occurrence of an uncontrolled condition. The challenge of "Making it Fail" becomes significantly greater when the failure transpires intermittently. Many intricate challenges exhibit intermittent patterns, which occasionally deter us from strictly adhering to this principle, given its inherent complexity. While you might precisely understand the steps that led to the initial failure, reproducing it consistently remains elusive – perhaps occurring only once in every five, ten, or even a hundred attempts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl7mf80ltzn4lz3qeu3f.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftl7mf80ltzn4lz3qeu3f.jpeg" alt="Image description" width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The critical aspect to recognize is that while you possess a clear understanding of the actions that triggered the failure, you lack exhaustive knowledge of all the precise conditions. Unnoticed or uncontrollable factors invariably play a role. Gaining mastery over these diverse conditions equips you to induce the failure consistently. However, circumstances may arise where certain conditions remain beyond your control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Signature
&lt;/h2&gt;

&lt;p&gt;It's crucial to possess the ability to closely examine the occurrence of the failure. In situations where the failure isn't consistent, you must thoroughly analyze it whenever it does happen, disregarding the numerous instances when it doesn't. The pivotal strategy involves gathering comprehensive data during each run, allowing you to conduct an in-depth analysis once the failure has been confirmed. This can be achieved by generating extensive system output while it's operational and archiving this information within a designated "debug log" file.&lt;/p&gt;

&lt;p&gt;By scrutinizing the accumulated data, you can readily contrast a failed run with a successful one. If you manage to capture the relevant information, you'll likely discern discernible distinctions between instances of successful execution and those resulting in failure. Pay special attention to the factors unique to the failure cases. These distinctions form the basis of your investigation during the debugging process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9oic08rksae6kqy207rj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9oic08rksae6kqy207rj.jpg" alt="Image description" width="500" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even in scenarios where the failure occurs intermittently, this approach enables you to identify and document the occurrences systematically, thereby allowing you to address them as if they were consistently happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Barking up the wrong tree
&lt;/h2&gt;

&lt;p&gt;The second rationale behind inducing failure is to gain insights into its underlying cause. With intermittent issues, you might begin noticing patterns in your actions that appear connected to the failure. While this can be useful, it's important to exercise caution and not become excessively fixated on these patterns.&lt;/p&gt;

&lt;p&gt;In cases of random failures, obtaining a statistically significant number of samples to determine whether seemingly minor actions, such as clicking a button with your left or right hand, truly affect the outcome, is often unfeasible.&lt;/p&gt;

&lt;p&gt;Frequently, coincidences may lead you to believe that one condition increases the likelihood of the problem compared to another. This can lead you down a path of investigating differences between conditions that might not actually be directly responsible for the issue, resulting in wasted effort.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ceo83kgcw6rdcjbyhdi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ceo83kgcw6rdcjbyhdi.jpg" alt="Image description" width="288" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this doesn't discount the possibility that the observed coincidental differences are somehow related to the bug. Yet, if these differences don't exert a direct influence, they can easily be overshadowed by other random factors, making it challenging to deduce a clear connection.&lt;/p&gt;

&lt;p&gt;By accumulating a substantial volume of information, you can distinguish elements consistently associated with the bug from those never linked to it. These are the aspects you should concentrate on while exploring plausible causes of the problem.&lt;/p&gt;

&lt;p&gt;Undeniably, randomness complicates the process of confirming a fix. For instance, if the test reveals a 10% failure rate, and your intervention reduces it to 3% — but you cease testing after 28 attempts — you might believe the issue is resolved, even though it isn't.&lt;/p&gt;

&lt;p&gt;While employing statistical testing is beneficial, it's even more advantageous to identify a sequence of events invariably linked to the failure, even if the occurrence of the sequence is intermittent. When the sequence arises, failure is guaranteed. Therefore, after implementing a potential fix, continue testing until the sequence transpires. If the sequence manifests without the associated failure, you've successfully rectified the bug. Don't prematurely conclude after 28 attempts if the sequence hasn't surfaced yet. &lt;/p&gt;

&lt;h2&gt;
  
  
  Black swans
&lt;/h2&gt;

&lt;p&gt;It is easy to just neglect the warning signs and ignore the arguments by other people who insist on the existence of the bugs like customers, quality assurance people. You ego can stand in your way from understanding and perceiving the unknown nature of the bug. But you can't simply deny the possibility of the occurrences. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Know that "that" can happen&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The absence of evidence does not mean the evidence of absence. Remember, people simply denied the existence of Black swans until they see one. The world of software and hardware is a type of Extremistan, where there is a high probability of unexpected events to happen. And when you see one Black swan, it's time to ditch your assumptions and think about devising a completely new strategy to find new ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never throw away a debugging tool
&lt;/h2&gt;

&lt;p&gt;Occasionally, a testing tool can find application in various debugging scenarios. When designing such a tool, it's crucial to consider its potential for reuse and ensure it remains maintainable and adaptable. Achieving this entails employing sound engineering practices, creating comprehensive documentation, and incorporating it into your source code control system. Integrate it seamlessly into your systems to ensure accessibility in real-world scenarios. Refrain from treating it as a disposable tool; your initial assumption of its limited utility might be inaccurate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos7nxzlz720m9h8uw3ua.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos7nxzlz720m9h8uw3ua.jpeg" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Occasionally, a tool proves so invaluable that it could even be marketable; there are instances where companies have shifted their business focus upon realizing that the tool they developed possesses greater appeal than their original products. A tool's usefulness can extend beyond your initial expectations, presenting possibilities you might not have conceived of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you really haven't any idea what could be wrong, life gets tougher!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Initiate the process by ensuring that you can prompt the bug to manifest consistently. It can be exasperating to pursue a bug that doesn't materialize with every occurrence. Invest time in crafting input data and configuring parameters that consistently trigger the issue, subsequently packaging these steps into a streamlined procedure that facilitates effortless and automated execution. Especially when dealing with a challenging bug, you'll find yourself repeatedly reproducing it as you unravel the underlying cause. Thus, streamlining the reproduction process will ultimately save you valuable time.&lt;/p&gt;

&lt;p&gt;When confronted with a bug that doesn't exhibit consistent behavior, devote effort to comprehending the reasons behind its intermittent nature.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>programming</category>
      <category>beginners</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
