In case of emergency, break the glass. Three debugging tips

What do you do when you’re facing a problem or have to fix a bug? Bang your head against the wall, smash your display? Here you have three debugging tips.

1. Isolate your problem

A coworker always says “Isolate your problem!” when you ask him for help. He’s right!

Start by removing all irrelevant parts from your problem. Is the problem in your database layer? In your JavaScript code? In your API controllers? Create an unit or integration test to recreate the conditions of your problem and the input that triggers it.

2. Stop and think

One of my takeaways from the book Pragmatic Thinking and Learning is thinking how to deliberately create the bug you’re facing. Run experiments to test your hypothesis.

Debugging is thinking. Pen and paper are your friends.

Sometimes you have to explain your problem to somebody else. And, the answer seems to come by magic. You don’t have anyone around?-you said. Think out loud or explain it to a rubber duck.

Your best debugging friend. Photo by Allison Astorga on Unsplash

3. Find how others have solved your problem

Chances are somebody else has already faced and solved the same problem or a similar one. If you look out there, you might find an StackOverflow answer or a GitHub issue. Don’t blindly copy and paste any code without understanding it first. And, always prefer battle-tested solutions.

Voilà! These are three tips I have learned to use when facing an issue or figuring out how to solve a bug. One final tip: step away from your keyboard. That would make the diffuse mode of your brain to work.

Are you curious about problem solving and learning in general? Check my takeaways from the book Pragmatic Thinking and Learning and the book Ultralearning.

Happy debugging!

Just Vim It! Learning Vim For Fun and Profit

Have you ever heard about Vim? You might know it only as the text editor you can’t even close if you don’t know a key combination. But, once you know Vim, you can edit text files at the speed of light. Let’s see why you should learn it and how to start using it!

What is Vim?

From Vim’s official page, Vim

“…is a highly configurable text editor built to make creating and changing any kind of text very efficient”.

Vim is short for Vi IMproved. Vim is a fork of the Unix vi editor. Vim is free and open-source. It dates back to the times when the arrow keys and the Esc key were in the middle row of keyboards.

Vim is a command-line editor. However, you can find it these days outside the command line with a graphical user interface. You can even bring the Vim experience to some IDE’s using plugins or extensions.

What makes Vim different?

Vim is a distraction-free text editor. You won’t find fancy toolbars full of icons. You will find a blank canvas ready to start.

Vim works in modes. Vim has three modes: normal, insert, and visual. In each mode, you can perform only certain types of actions. In normal mode, you can run commands on your text; copy and paste, for example. In insert mode, you can type words and symbols. In visual mode, you can select text.

Vim includes the concept of macros. You can record a sequence of actions and repeat it over a stream of text. Using macros, you don’t need to retype the same key combination over and over on the text you want to edit.

Vim integrates with your command line. If you need to compile, run your tests, or do any other action in the command line, you can do it without leaving your editor. Even you can import the output of a command right into your text.

Vim can be extended and customized. You can bring your favorite color scheme and define your own key shortcuts. There are lots of plugins to enhance your experience with Vim.

Macro typewriter ribbon
Photo by Dung Anh on Unsplash

Why you should learn Vim? A note on Productivity

Vim helps you to stay away from your mouse. It reduces the small context switching of reaching your mouse making you a bit faster. You can move inside your files and edit them without leaving your keyboard. Your hands will be in the middle row of your keyboard all the time.

With Vim you can move to almost anywhere in a file with a few keystrokes. You can go to the previous or next word, to the beginning or end of your line and file, to any character in the current line.

Vim uses text object motions. You can copy, change or delete anything inside parenthesis, braces, brackets, and tags.

Change the parameter list of a method

Let’s say your cursor is at the beginning of a line, and you need to change the parameter list of a method. How would you do it? What keystrokes do you need?

Without Vim, you place your cursor in the opening parenthesis with the mouse. Then, while holding Control and Shift, you press the right arrow until the closing parenthesis.

Change the parameter list of a method without Vim
Change the parameter list of a method without Vim

But, with Vim, you need fewer keystrokes. You go to the opening parenthesis with f(. Then press ci( to change everything inside the parenthesis. Faster, isn’t it?

Change the parameter list of a method with Vim inside Visual Studio
Change the parameter list of a method with Vim inside Visual Studio

How to start learning Vim

Vim has a steep learning curve. Don’t try to do your everyday work with Vim right from the beginning.

If you’re only used to Control + C and Control + V from other editors, you will have to learn new shortcuts for everything. Literally, everything. It can be frustrating and unproductive when you first open Vim.

To learn Vim, learn the basic motions and commands, and start editing files from the command line or an online Vim emulator outside of everyday work. Have a cheatsheet at hand.

If you are working in a Unix-based operating system, chances are you have Vim already installed. If not, you can install it from its official site or with a package manager, such as brew, apt-get or chocolatey, depending on your operating system.

How to exit Vim

Let’s answer the question from the beginning of the post once and for all.

First, how can you exit Vim if, by any chance, you end up inside it? Did you try to commit from the command line without changing Git default editor? Press :q! and Enter. It will exit Vim and discard any changes. That’s it!

To exit saving your changes, press :wq and Enter. Also, you can press ZZ and Enter. Your changes will be saved this time.

How to enter and exit Vim modes

You need to switch back and forth between the three modes: normal, insert, and visual modes. In a normal text editor, you work in the three modes at the same time. But with Vim, you need to switch between them.

To open a file with Vim, from the command line type vim <your-file>. Change <your-file> with the actual name of the file. When you open a file, you will be in normal mode.

To start editing your file, you need to switch to insert mode. Press i. You will see the -- INSERT -- label in the status bar. Now, you can type any text. To exit insert mode, press Esc. You’re back to normal mode.

To select some text, switch to visual mode pressing v. The status bar will display -- VISUAL --. You can select lines of text like using the mouse. Again, to switch back to normal mode, you need Esc. Don’t worry! Once you’re used to these modes, you will switch almost unconsciously.

How to move through a file with Vim

With Vim, you can use the arrow keys to move your cursor around. But, to keep your hands in the middle row, you can use h, j, k, l instead of Left, Down, Up, and Right, respectively.

Instead of using arrow keys to move the cursor one position at a time, learn some basic motions.

These are some of the basic Vim motions:

Vim Action
b Go to the previous word
w Go to the next word
0 Go to the beginning of the current line
$ Go to the end of the current line
gg Go to the beginning of the file
G Go to the end of the file
<number>gg Go to line with number <number>
f<char> Go to the next instance of <char> in the current line
I Go to the beginning of the current line and enter insert mode
A Go to the end of the current line and enter insert mode
{ Go to the previous paragraph
} Go to the next paragraph

Add a semicolon at the end of a line with Vim

Do you want to see motions in action? Did you forget to add a semicolon at the end of a line? In normal mode, type A; on the line missing the semicolon.

Vim Action
<number>gg Go to the line number <number>. The line missing the semicolon
A Go to the end of the line and enter insert mode
; Insert ;
Esc Go back to normal mode
Add a missing semicolon to a line with Vim
Add a missing semicolon to a line with Vim

How to copy and paste in Vim

A common task while programming and editing text, in general, is to copy and paste. Vim can copy and paste too. Well, how do we copy and paste with Vim? Vim calls these actions yank and put.

To copy, enter visual mode, select some text, and press y. Then move to the desired place and press p. Vim will put the yanked text below the cursor position. You can copy an entire line with yy.

Copy and paste a line with Vim
Copy and paste a line with Vim

What about cut and paste? Vim deletes and puts. To cut and paste, instead of pressing y to copy, you need to use d to delete. Then, p to put the cut text in the desired location. Similarly, to delete an entire line, you need dd.

Besides y and d, you can change some text with c. It will remove the selected text and enter insert mode.

Text objects

You can use y, d and c to edit text inside parenthesis (, braces {, brackets [, quotes '" and tags <>. These patterns of text are called text objects.

Text objects are useful to edit text inside or around some programming constructs. Parameter list, elements of an array, a string, a method body, and everything inside an HTML tag.

That’s why to change a parameter list, you can use ci( to change everything inside ().

How to start using Vim?

Once you are comfortable editing and moving around your files with Vim, you can use it inside your IDE. You can start using Vim inside Visual Studio installing VsVim extension and inside Visual Studio Code with VSCodeVim.

Make sure to have a cheatsheet next to you. So you can look up commands if you get stuck. Don’t try to learn all the commands at once. Learn one or two commands at a time and practice them.

Conclusion

Voilà! Now you know how to exit Vim, switch between modes, and move around a file. That’s what you need to get started with Vim.

There are more things to cover, like searching and replacing, undoing and redoing, and using tabs, among other features. It’s true that Vim has a steep learning curve. Give it a try! You might find yourself Viming the next time.

This post was originally published on exceptionnotfound.net as part of the Guest Writer Program. I’d like to thank Matthew for editing this post.

If you want to boost your productivity with Visual Studio, check my Visual Studio Setup to see the theme, settings, and extensions I use.

Happy Vim time!

How I got rid of two recurring review comments (Git hook, VS extension)

These are two things I always forgot to do when opening my code to code review. To save my reviewers and me some time, I decided to do something about it. This is how I get rid of two recurrent comments I got getting my code reviewed.

For a project I was working on, I had to include the ticket number in every commit message and add Async suffix to all asynchronous C# methods. I forgot these two conventions every time I created my Pull Requests.

1. How to add ticket numbers in commit messages

Add ticket numbers in Git commit messages using a prepare-commit-msg hook. This hook formats commit messages before committing the changes. Use this hook to enforce naming conventions and run custom actions before committing changes.

I was already naming my feature branches with the ticket number. Then, with a bash script I could read the ticket number from the branch name and prepends it to the commit message.

This is a prepare-commit-msg hook to prepend commit messages with the ticker number from branch names.

#!/bin/bash
FILE=$1
MESSAGE=$(cat $FILE)
TICKET=[$(git branch --show-current | grep -Eo '^(\w+/)?(\w+[-_])?[0-9]+' | grep -Eo '(\w+[-])?[0-9]+' | tr "[:lower:]" "[:upper:]")]
if [[ $TICKET == "[]" || "$MESSAGE" == "$TICKET"* ]];then
  exit 0;
fi

echo "$TICKET $MESSAGE" > $FILE

If I name my feature branch feat/ABC-123-my-awesome-branch. Then when I commit my code, Git will rewrite my commit messages to look like ABC-123 My awesome commit.

I wrote about this hook on my list of Programs that saved me 1000 hours, where I listed the Git aliases, Visual Studio extensions and other online tools to save me some valuable time.

2. Don’t miss Async suffix on asynchronous C# methods

Another convention I always forgot about was adding Async suffix on asynchronous C# methods.

Use a .editorconfig file

After Googling a bit, a coworker came up with this StackOverflow answer to use a .editorconfig file to get errors on async methods missing the Async suffix.

This is how to enforce the Async suffix inside an .editorconfig file,

[*.cs]

# Async methods should have "Async" suffix
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods
dotnet_naming_rule.async_methods_end_in_async.style = end_in_async
dotnet_naming_rule.async_methods_end_in_async.severity = error

dotnet_naming_symbols.any_async_methods.applicable_kinds = method
dotnet_naming_symbols.any_async_methods.applicable_accessibilities = *
dotnet_naming_symbols.any_async_methods.required_modifiers = async

dotnet_naming_style.end_in_async.required_prefix = 
dotnet_naming_style.end_in_async.required_suffix = Async
dotnet_naming_style.end_in_async.capitalization = pascal_case
dotnet_naming_style.end_in_async.word_separator =

But, the .editorconfig enforces Async suffix even Main method and tests names. MainAsync looks weird. Also, it misses method declarations returning Task or Task<T> on interfaces. Arrggg!

AsyncMethodNameFixer Visual Studio extension

To add a warning on asynchronous C# methods missing the Async suffix, use the AsyncMethodNameFixer extension on Visual Studio.

With the AsyncMethodNameFixer extension, I get warnings when I don’t include the Async suffix on methods and interfaces. It doesn’t catch the Main method and test methods.

But, to enforce this convention across the team, I have to rely on the other developers to have this extension installed. With the .editorconfig, all the naming rules travels with the code itself when anyone clone the repository.

Voilà! That’s how I got rid of these two recurring comments while code review. For more productive code reviews, read my Tips and Tricks for Better Code Reviews.

For more extensions to make you more productive with Visual Studio, check my Visual Studio Setup for C#.

If you’re new to Git, check my Git Guide for Beginners and my Git guide for TFS Users.

Happy coding!

How I take notes?

Some time ago, I commented on a discussion on dev.to titled How do you make notes?. Here is my long reply.

Plain text and Markdown

I love plain text. It’s future-proof. I can use any text editor to edit text files. Notepad++, SublimeText, Vim, Visual Studio Code, you name it. I use plain text for almost everything.

I write all my notes using Markdown. It’s formatted plain text that renders to HTML. Markdown is already on README files in GitHub and almost everywhere on the Internet.

I write and organize my notes with Notable. It’s clean and simple.

A pencil and a notebook
Photo by Jan Kahánek on Unsplash

todo.txt and Zettelkasten

For my task list, I have a todo.txt file. One task per line. Each task has a priority, due date, and optional tags.

For ideas and future tasks, I have a later.txt. Once a task is done, I move it to a done.txt file. I keep it as a brag document.

I have one note per file for every blog post, podcast, video, and book I find interesting. I group these notes using the tag: “til,” short for “Today I learned.” I write the date, source, key points, and my reaction.

I capture ideas and thoughts on my phone. From the book Pragmatic Thinking and Learning, I learned to “always have something to keep notes.”

Recently I found a note-taking system: Zettelkasten. In short, we write our learning in our own words on a paper or card, put an index number, and connect it to our existing notes. Although there are editors for Zettelkasten, I have my own slip-box and keep my cards with pen and paper.

UPDATE (Jun 2023): These days, I’ve been playing with a todo.txt per day and a Bash script to start a new workday by importing the pending tasks from the previous day. Also, in the same spirit of todo.txt, I found calendar.txt, a plain text calendar, and this Bash oneliner to open the calendar.txt file in the current date with Vim.

To read more about the Zettelkasten method, check my takeaways from the book How to Take Smart Notes. For more ideas on plain text files, check these ten clever uses for plain text on Lifehacker.com.

Happy note-taking!

How to read configuration values in ASP.NET Core

Let’s see how to read and overwrite configuration values with ASP.NET Core 6.0 using the Options pattern.

To read configuration values following the Options pattern, add a new section in the appsetttings.json file, create a matching class, and register it into the dependencies container using the Configure() method.

Macaroons in the showcase of a pastry shop
Those are Macaroon options. Not the Options pattern. Photo by Vered Caspi on Unsplash

Let’s see how to use, step by step, the Options pattern to read configuration values.

1. Change the appsettings.json file

After creating a new ASP.NET Core API project with Visual Studio or the dotnet tool from a terminal, let’s add in the appsettings.json file the values we want to configure on a new JSON object.

Let’s add a couple of configuration values inside a new MySettings object in our appsettings.json file like this,

{
  "MySettings": {
    "AString": "Hello, there!",
    "ABoolean": true,
    "AnInteger": 1,
    "AnArray": ["hello", ",", "there", "!"]
  }
}

Inside the appsettings.json file, we can use booleans, integers, and arrays, not only strings.

2. Create and bind a configuration class

Then, let’s create a matching configuration class for our configuration section in the appsettings.json file.

We should name our configuration class after our section name and its properties after the keys inside our section.

This is the configuration class for our MySettings section,

public class MySettings
{
    public string AString { get; set; }
    public bool ABoolean { get; set; }
    public int AnInteger { get; set; }
    public string[] AnArray { get; set; }
}

Next, let’s bind our configuration class to our custom section and register it into the built-in dependencies container. In our Program.cs class, let’s use the Configure() method for that,

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var mySettingsSection = builder.Configuration.GetSection("MySettings");
builder.Services.Configure<MySettings>(mySettingsSection);
//               ^^^^^

var app = builder.Build();
app.MapControllers();
app.Run();

As an alternative, we can use GetRequiredSection() instead. It throws an InvalidOperationException if we forget to add the configuration section in our appsettings.json file.

3. Use sections and subsections

Let’s use sections and subsections to group our configuration values on appsettings.json files.

Now let’s say MySettings is inside another section: AllMyCoolSettings. We need a new AllMyCoolSettings class containing a MySettings property like this,

public class AllMyCoolSettings
{
    public MySettings MySettings { get; set; }
    //     ^^^^^
}

Then, in the Configure() method, we separate the section and subsection names using a colon, :, like this,

var mySettings = builder.Configuration.GetSection("AllMyCoolSettings:MySettings");
//                                                 ^^^^^
builder.services.Configure<MySettings>(mySettings);

4. Inject an IOptions interface

To use these configuration values, let’s add an IOptions<T> parameter in the constructor of our service or controller.

Let’s create a simple controller that prints one of our configured values,

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly MySettings _mySettings;

    public ValuesController(
        IOptions<MySettings> mySettingsOptions)
        // ^^^^^
    {
        _mySettings = mySettingsOptions.Value;
        //                              ^^^^^
    }

    [HttpGet]
    public string Get()
    {
        return _mySettings.ASetting;
        //     ^^^^^   
    }
}

The IOptions<T> interface has a property Value. It holds an instance of our configuration class with the parsed values from the appsettings.json file.

In our controller we use the injected MySettings like any other object instance.

By default, if we forget to add a configuration value in the appsettings.json file, ASP.NET Core doesn’t throw any exception. Instead, ASP.NET Core initializes the configuration class to its default values.

That’s why it’s a good idea to always validate for missing configuration values inside constructors.

For unit testing, let’s use the method Options.Create() with an instance of the MySettings class we want to use. We don’t need a stub or mock for that!

5. Use separate configuration files per environment

Let’s separate our configuration values into different configuration files per environment.

By default, ASP.NET Core creates two JSON files: appsettings.json and appsettings.Development.json. But we could have other configuration files, too.

If ASP.NET Core doesn’t find a value in an environment-specific file, it reads the default appsettings.json file instead.

ASP.NET Core reads the current environment from the ASPNETCORE_ENVIRONMENT environment variable.

On a development machine, we can use the launchSettings.json file to set environment variables.

For example, let’s override one configuration value using an environment variable in our launchSettings.json file,

{
    "<YourSolutionName>": {
      "commandName": "Project",
      "applicationUrl": "http://localhost:5000",
      
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        // ^^^^^
        "MySettings__AString": "This value comes from an environment variable"
        // ^^^^^
      }
    }
  }
}

By default, ASP.NET Core reads configuration values from environment variables, too.

Environment variables have a higher precedence than JSON files.

For example, if we set an environment variable MySettings__AString, ASP.NET Core will use that value instead of the one on the appsettings.json file.

Notice that the separator for sections and subsections inside environment variables is a double undescore, __.

6. Embrace PostConfigure

After registering our configuration classes, we can override their values using the PostConfigure() method.

I used PostConfigure() when refactoring a legacy application. I grouped related values in the appsetting.json file into sections. But I couldn’t rename the existing environment variables to match the new names. I did something like this instead,

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var mySettingsSection = builder.Configuration.GetSection("MySettings");
builder.Services.Configure<MySettings>();

builder.Services.PostConfigure<MySettings>(options =>
//               ^^^^^
{
    var anOldSetting = Environment.GetEnvironmentVariable("AnOldSettingName");
    //  ^^^^^
    if (!string.IsNullOrEmpty(anOldSetting))
    {
        options.AString = anOldSetting;
        //      ^^^^^
    }
});

var app = builder.Build();
app.MapControllers();
app.Run();

Conclusion

Voilà! That’s how to read configuration values with ASP.NET Core 6.0. Apart from the IOptions interface we used here, ASP.NET Core has IOptionSnapshot and IOptionsMonitor. Also, we can read values from INI files, XML files, or Azure Key Vault.

In the days of the old ASP.NET framework, we had a ConfigurationManager class and a web.config file to read configuration values. Those days are gone! We have JSON files now.

For more ASP.NET Core content, check how to create a caching layer, how to create a CRUD API with Insight.Database, and how to use background services with Hangfire.

Happy coding!