Tuesday, November 9, 2021

Stateful iterators in Go

I’m writing an insane amount of Go code lately. It’s really unobtrusive, allowing you focus on the problem you have to solve. And I’ve been dabbling with iterators in Go for a while, since I started to used them in Rust – which is so much better than C++ in this regard.

Today, when researching the topic again, I found a very nice article on the matter, exploring a few possibilities. The most performant approach is a stateful iterator, which can be implemented as:

type IterFive struct {
	count int
}

func NewIterFive() IterFive {
	return Iter{}
}

func (it *IterFive) Value() int {
	it.count++
	return it.count - 1
}

func (it *IterFive) Ok() bool {
	return it.count < 5
}

func main() {
	for iter := NewIterFive(); iter.Ok(); {
		println(iter.Value())
	}
}

I’m still unsure whether I should adopt interators instead of simply allocating and returning slices for some functions, but I’m considering it. The main reason would be performance, but it could be qualified as premature in the cases I’m dealing with in Windigo.

Friday, November 5, 2021

Static linking of the C runtime in Rust

By default, Rust on Windows with MSVC toolchain compiles to a dynamically linked C runtime, apparently following the default configuration on Visual Studio, which uses the /MD compiler flag. In order to use static linking for the C runtime, we must change this to /MT, something I’m used to do in my C++ Visual Studio projects.

I found notes about Rust linkage, which hints us specifically about these /MD and /MT switches, although not citing them explicitly. The way to specify static linking is through RUSTFLAGS environment variable:

RUSTFLAGS='-C target-feature=+crt-static' cargo build --release --target x86_64-pc-windows-msvc

Which is rather ugly, let me say. At least it appears to work, and this is the command line I’m using for my release builds now.

Friday, October 22, 2021

Displaying custom fields in foobar2000

Today I found the TOPE frame in the ID3v2 tag specification, which can be used in cover songs. I was simply using the comment frame so far, and having a specific frame for that is great. Now I needed to display this frame in foobar2000, my player of choice for years.

I created an account in foobar2000 forums and posted the question there. Then I just found a specific subreddit, and I posted the same question.

Much to my amusement, I got answers in both after a few minutes.

Turns out, I vaguely remember having done this before. One must navigate to Preferences > Advanced > Display > Properties dialog > Standard fields, and add:

Original Artist=ORIGINAL ARTIST;

And it worked.

Tuesday, September 28, 2021

Enhancing Chrome 94 privacy

Unfortunately Firefox is getting worse every day, specially after the introduction of the horrible v89 interface. Having to resort to Chrome again demands some precautions.

Latest Chrome 94 introduced an idle detection feature, which is a privacy nightmare. Fortunately, we still can disable it here:

chrome://settings/content/idleDetection

And don’t forget to also disable the privacy sandbox and FLoC features:

chrome://settings/privacySandbox

I really wish I could go back to ol’ good Firefox.

Friday, September 17, 2021

My Visual C++ 2019 settings

Just for the record, these are the settings I’m always using with Visual Studio 2019, when creating a new, empty C++ project:

  • General
    • Output Directory: $(SolutionDir)$(Platform)_$(Configuration)\
    • Intermediate Directory: $(Platform)_$(Configuration)\
    • C++ Language Standard: ISO C++20 Standard (/std:c++20)
  • C/C++
    • General
      • Debug Information Format: None (Release)
      • Treat Warning As Errors: Yes (/WX) (Release)
      • Multi-processor Compilation: Yes (/MP)
    • Code Generation
      • Runtime Library: Multi-threaded (/MT) (Release)
  • Linker
    • Debugging
      • Generate Debug Info: No (Release)
    • System
      • SubSystem: Windows (/SUBSYSTEM:WINDOWS)

As of April 2024, the settings above also apply to Visual Studio 2022.

Tuesday, September 14, 2021

Adding a branch from another repo in Git

This should be something rather rare, but for some reason I keep needing to do it very often: I want to add a new, unrelated branch into an existing repository, and this branch comes from another repository.

While needing to do this yet again today, I found a rather elegant solution here:

git switch --orphan NEW_BRANCH
git pull FORK_URL FORK_BRANCH

It works remarkably well and clean. Props to the guy who shared this.

Tuesday, August 3, 2021

Deep cloning a generic List in Java

Today I had to deep clone objects in Java. What a nightmare.

First, the Cloneable interface is horribly broken, and writing such a simply code becomes a laborious task. Second, if the object has a List as a field, you must manually clone the elements into a new List.

The code goes as it follows:

public class Foo implements Cloneable {

	private String name;

	private List words;

	@Override
	public Object clone() {
		try {
			Foo cloned = (Foo) super.clone();
			cloned.words = Auxiliar.cloneList(words);
			return cloned;
		} catch (CloneNotSupportedException e) {
			System.out.println("Never happens!");
			return null;
		}
	}

	// Getters and setters omitted.

}

Notice the Another.cloneList() call? This is where we manually clone all the List elements, by calling clone() in each one. This is the solution I found for a generic method:

public class Auxiliar {

	@SuppressWarnings("unchecked")
	public static <T extends Cloneable> List<T> cloneList(List<T> list) {
		try {
			List<T> newList = new ArrayList<>(list.size());
			for (T item : list) {
				newList.add((T) item.getClass().getMethod("clone").invoke(item));
			}
			return newList;
		} catch (IllegalAccessException | IllegalArgumentException
			| InvocationTargetException | NoSuchMethodException | SecurityException e) {
			System.out.println("Never happens!");
			return null;
		}
	}
}

No idea why Cloneable was not deprecated and replaced by something minimally decent yet.