Monday, March 16, 2020

Choosing between useState and useReducer in React

Right now I’m designing a rather important architecture at work, and I’m using React for it. After writing a simple enough implementation with Redux, I came to the conclusion that, in fact, I don’t need Redux in this architecture, since I’m only storing auth information. Context API seems to be enough.

So, in order to have a mutable and reactive value in the application context, I must choose between useState and useReducer hooks.

While studying the matter, I found a rather good answer to this question:

  • When it’s just an independent element of state you’re managing: useState;
  • When one element of your state relies on the value of another element of your state in order to update: useReducer.

Although the examples given by the author are way too long, the idea is spot on. In my particular case, since the state is just a monolithic block of data, useState seems to fit my needs.

Wednesday, February 5, 2020

False memory leak reports of static objects

I was having a weird memory leak report in a C++ program, happening right after I close it, and triggered by a call to _CrtDumpMemoryLeaks, which exists in the very end of WinMain function in WinLamb. I was puzzled, because I’ve commented everything out, and I still had the memory leak.

Turns out _CrtDumpMemoryLeaks is called at the end of WinMain, before the static object destructors are called. And there you go: if any statically allocated object had made a heap allocation, the memory won’t be freed yet, thus the report.

I’m not the only one with this problem, but so far no solution had any effect. By now I’ll just avoid static allocation of objects which alloc memory on the heap, and carry on with life. Maybe I’m too used to the JavaScript blessings.

Thursday, January 9, 2020

What types are heap-allocated in Rust

Today I stumbled on this question regarding which standard Rust types do alloc in the heap. I have this question popping in my head quite often, so here are the heap-allocated ones:

  • Box, simple heap allocation;
  • Rc, reference counter;
  • Arc, thread-safe atomic reference counter;
  • collections.

Reference to the answer can be found here.

Monday, January 6, 2020

Firefox: can’t see menu separators in Linux

In Linux, I was having a problem when using Firefox. After some version update, the menu separator lines simply disappear. After searching around after a solution to this very annoying problem, I found another userChrome.css customization:

/* Make separators in menus easier to see */
menuseparator {
  -moz-appearance: none !important; /* nothing changes without this */
  background: #d4d2d1 !important;
  height: 1px !important;
  padding: 0 !important;
  margin: 3px 5px !important;
}

Make sure it’s loading is enabled. After restarting Firefox, the menu separators were back in all their glory.

Friday, December 27, 2019

Restore loading blue circle throbber in Firefox

Since Firefox 57 the loading icon has changed. Previously you’d see a blue circle spinning, now you see a dot moving horizontally. Personally, I prefer the old one.

So there’s this tip I found a while in the fantastic /r/FirefoxCSS Reddit, which restores the old throbber. Fortunately, Firefox developers kept the old animation file within the package, so we can still use them.

The following CSS must be added to “userChrome.css” file:

/* Revert tab throbber - for Nightly 57 as of 9/20/2017 */
.tab-throbber[busy]::before {
  background-image: url('chrome://global/skin/icons/loading.png') !important;
  animation: unset !important;
}
.tab-throbber[busy]:not([progress])::before {
  /* Grays the blue during "Connecting" state */
  filter: grayscale(100%);
}
@media (min-resolution: 2dppx) {
  .tab-throbber[busy]::before {
    background-image: url('chrome://global/skin/icons/loading@2x.png') !important;
  }
}

The “userChrome.css” is located in your Firefox profile folder. If it doesn’t exist, you can create it. Also, make sure it’s loading is enabled.

Thursday, October 17, 2019

Override Chrome policy in Linux

If you happen to have Google Chrome settings managed by your network administration, on Linux, the fixed settings are stored into JSON files in the folder:

/etc/opt/chrome/policies/

If you have write permissions, you can change the settings you want. You don’t even need to restart Chrome to the changes start working. This has been tested in Chrome 77.

Wednesday, October 16, 2019

Let Go website generate your documentation

When trying to figure out how go doc command works, I just found out that I don’t need to use it.

There’s an incredible feature of Go documentation website: it can generate and display the documentation of all your project, straight from GitHub – and other websites too. The generated HTML is very polished.

To use it, append your GitHub user name and repo to their URL, such as:

https://godoc.org/github.com/username/reponame

Even more interesting: all types and Go built-in types are automatically linked. And it also provides direct links to GitHub source files. On top of all that, it’s very fast. Written in Go, I suppose.

Being a C language admirer, the more I work with Go, the more I like its simplicity.

Wednesday, October 9, 2019

Using Go modules in separated local directories

Suppose I have a Go project, “foo”, which writes to the console. In this project, I have some .go files which have all the functions that actually write to the console.

Now I want to make these writing routines a separated module: “writer”, in another directory. I want two sibling directories: “foo” and “writer”. The “writer” will be used as a dependency within “foo”.

Within “writers” folder, run go mod init writer to create the go.mod file. Back in “foo”, edit its go.mod adding the new dependency:

module Foo

go 1.13.1

require (
  shoutergo v0.0.0
)

replace (
  shoutergo => ../shoutergo
)

The replace line will inform Go where to look for the module. Without it, Go will search in the internet, that’s why GitHub URLs work right away.

The version of the dependency, as far as I could find, is a Git tag, and to local modules it’s completely irrelevant, although necessary.

Now, in “foo”, we can import “writer” just like any other package:

import (
  "writer"
)

func main() {
  writer.SomeFunc()
}

As I keep learning Go and exploring the limits of the language, although I’m not entirely satisfied – lack of enums and namespaces –, I’m very pleased with its design choices with opted for simplicity. Feels like a better C.

Thursday, October 3, 2019

How Go caches downloaded packages

Here I intend to summarize how the Go package cache system works, after spending half of my afternoon running tests and figuring out this weird thing.

First off, to create a new Go project outside the awful GOPATH directory, you run:

mkdir my-project
cd my-project
go mod init my-project

This will create a go.mod file.

To add a dependency from GitHub, you run:

go get github.com/username/reponame

This will create a go.sum file, which contains the dependency tree. The package files themselves will be downloaded and buried within ~/go/pkg/mod directory, so they are effectively cached at global, machine-wide scope.

To list the packages inside my-project, run:

go list ./...

This won’t list globally downloaded, cached dependencies installed with go get.

To list the packages installed (not the cached ones) globally, run:

go list ...

Downloaded dependencies will be listed if you are in my-project folder, and if they have been downloaded already. If you run the command above from within a project directory, it will download and install any missing packages for current project, and then they will be listed.

So, if you’re outside my-project directory, there’s no way to list globally cached packages.

There’s no way to remove a globally cached package from cache individually. All you can do is delete the whole cache, with:

go clean -cache -modcache -i -r

Tuesday, October 1, 2019

CSS grid with column flow, with a nested grid

This month I was trying to layout a very complex form in two columns, and I ended up with this CSS sorcery. It’s important to notice that the number of columns and rows must be tightly controlled via their widths and heights.

Friday, September 20, 2019

The joy of Git Submodules

I’ve been using Git Subtrees for more than two years to manage the dependencies of my projects in Git. Today I found this article explaining Git Submodules, and I realized that I had it all wrong. Submodules suits my needs much better.

I finished migrating my C++ repositories which have WinLamb as a dependency. The nested “winlamb” folder effectively acts as a separated repository, without interfering with the top one. No more annoying merges with a huge hash as the commit message, when updating the library.

Monday, September 16, 2019

Rust for C++ programmers in 30 minutes

From time to time I get back to studying Rust, which looks like a good alternative to the unthinkable complexity of C++ for native programming, which even after about 20 years, still upsets me tremendously. From the perspective of a seasoned C++ programmer like me, the Rust concept of lifetimes has been particularly esoteric.

Fortunately, I found a great resource online today:

30 minutes of Introduction to Rust for C++ programmers

It’s a very concise online book with direct comparisons between C++ and Rust codes, exactly what I was after. It explains Rust basic concepts by direct comparison to C++, what greatly helps. Although you’ll need a little over 30 minutes to properly digest it, it’s well worth reading, and I consider to be the greatest introductory material so far to C++ programmers who want to dig into Rust.

Props to vnduongthanhtung, who authored the book back in 2017.