I recently decided to add support for light and dark color schemes to this site. Modern CSS makes this surprisingly painless: :root { color-scheme: light dark; --text: light-dark(#444, #bbb); --link: light-dark(#0076d1, #e27a11); } body { color: var(--text); } a { color: var(--link); text-decoration-color: oklch(from currentColor l c h / 50%); &:visited { color: oklch(from var(--link) calc(l - 0.3) c h); } } blockquote { background: light-dark(#f9f9f9, #1a1a1a); border-left: 10px solid light-...| citizen428.net
Note: This was originally posted as a Mastodon thread but since my posts there auto-delete after a while I decided to keep a a slightly modified version here too. The other day, I read this post titled What We Lost with PHP and jQuery. I never really was a PHP developer. I dabbled a bit, sometime around PHP 4.2 or so. I didn’t particularly like it. I checked in once with PHP 7 for some hackathon-type thing, and it had gotten much better already.| citizen428.net
Over the past year or so, something unexpected happened: TypeScript has seemingly become my most used scripting language, thanks in no small part to Deno. There are quite a few reasons for this: It’s well suited for my recent scripting needs which involved a lot of ETL tasks with CSV and JSON files, as well as REST APIs as data sources. I also had to write quite a few data migrations for a Firestore database, another area where TypeScript seemed like a good choice.| citizen428.net
Note: This was originally posted as a Mastodon thread but since my posts there auto-delete after a while I decided to keep a a slightly modified version here too. People often just share their success stories, but over the past two years, I was involved in/co-founded 6 different projects. Five of them did not work out. That’s a lot of work for very little return (and I’m not even counting opportunity costs), and I’d be lying if I said that it didn’t also affect my confidence a bit. On...| citizen428.net
I recently got quite interested in a relatively new programming language called Uiua (pronounced “wee-wuh”), which its creator Kai Schmidt describes as follows: Uiua is a general purpose, stack-based, array-oriented programming language with a focus on simplicity, beauty, and tacit code. I’ve long been fascinated by array languages (like APL, J, or BQN), as well as stack languages like FORTH and Factor. Combining these two paradigms leads to very interesting and — in my opinion at lea...| citizen428.net
In a previous installment of this series, I wrote about adding a project-specific .pryrc to Ruby/Rails projects. However, over the past couple of years, IRB gained some nice features and I don’t use Pry much anymore because it’s one less dependency I need to worry about. That doesn’t mean I want to give up on per-project configuration files though, which turned out to be slightly more complicated with IRB. Configuration file lookup The way IRB and Pry load their configuration is signifi...| citizen428.net
Today I accidentally deleted a file which was not yet commited. I had a brief moment of panic because I had been working on this for a few hours but then luckily remembered that it’s relatively easy to undo a mistake like this if the file has at least been staged before: Use git-fsck to find the dangling blob: $ git fsck --lost-found Checking object directories: 100% (256/256), done. Checking objects: 100% (252/252), done.| citizen428.net
Over the last few days I used Vue.js to build a small Firefox extension called RelaxedReader. It’s your typical reading list/bookmarking tool, with a few important differences: You can store a maximum of 10 articles. If you add more, the oldest will get pushed out (FIFO). Items automatically expire after 30 days. No notifications, badges, unread counts or anything else that prompts anxiety and/or FOMO. No tracking, third party servers or API calls.| citizen428.net
I’m a bit sick, so I’m looking for things to kill the boredom. 2 days ago I read a blog post on HyperApp. Yesterday I cloned the app from this Medium post in it: I created the exact same app in React and Vue. Here are the differences. According to one comment, the React version weighs in at 127.24KB and Vue at 77.84 KB. HyperApp in a Parcel production build came out at 7.| citizen428.net
This is the first in a series of Ruby on Rails related quick tips I’m going to publish over the next few days/weeks. If I had to name the most underused tool in most Rails developer’s toolboxes, rails console --sandbox would be my choice. Here’s what the documentation has to say on it: If you wish to test out some code without changing any data, you can do that by invoking rails console --sandbox.| citizen428.net
When I couldn’t fall asleep last night 1 my sleep-deprived brain suddenly went “I bet you can’t write a Makefile for FizzBuzz.” While I obviously should have responded with Homer Simpson’s classic “Shut up, brain, or I’ll stab you with a Q-tip.”, it was too late, I had already nerd sniped myself. I fully expected to waste way too much time on this but it only (?) took a little over an hour to come up with a solution.| citizen428.net
One of the things I enjoy about Go is its standard library, which comes with batteries included. Sure, some packages (like flag) aren’t as powerful or ergonomic as the available alternatives but I’m generally willing to accept this in order to avoid dependencies. Testing The same also applies to Go’s built-in test support, the testing package. Let’s look at a typical test: package example import "testing" func Add(a, b int) int { return a + b } func TestAdd(t *testing.| citizen428.net
I somehow often end up working on a few branches in parallel and some things make my life easier: git switch -: Like the cd command git switch and git checkout take a - argument which takes you back to the previously checked out branch. $ git branch * citizen428/long-branch-name $ git switch main Switched to branch 'main' Your branch is up to date with 'origin/main'. $ git switch - Switched to branch 'citizen428/long-branch-name' Your branch is up to date with 'origin/citizen428/long-branch-n...| citizen428.net
You like clean commit histories. If something goes wrong you use --amend and carry on. Life is good. The problem Then it hits you, you forgot something in an older commit. So you have to reach for a heavier gun in the form of git rebase --interactive (or git rebase -i), which offers a handy fixup option: f, fixup = like "squash", but discard this commit's log message Let’s see this in action.| citizen428.net
The process of installing NixOS on a Raspberry Pi 3 is pretty straightforward, as they are fully supported upstream. However, the documentation is somewhat spread out and occasionally a bit outdated and/or confusing, so I thought it may be worthwhile to summarize my recent experience. Download an image from Hydra, NixOS’ CI tool. For the Pi 3 you’ll use an AArch 64 image of the latest release (currently 20.03), which can be found here.| citizen428.net
In today’s Rails quick tip we’ll look at my local development workflow, specifically tmux, Overmind, and tmuxinator. tmux tmux is what’s called a “terminal multiplexer”. The documentation explains what exactly that means as follows: It lets you switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal. The following screenshot shows a single tmux window with 3 panes: one displaying a greeting v...| citizen428.net
Yesterday I ended up writing an impromptu guide to Bash error handling on a PR, so I decided to polish it a bit and turn it into an actual post. The goal: whenever our release script encounters an error, send a notification to a Slack channel. We won’t look into the latter part in this post, as it was handled by some Ruby code using the slack-notifier gem. Instead we’ll look into what was necessary to make this work in Bash.| citizen428.net
ReasonML — Reason for short — is an alternative syntax and toolchain for OCaml, a mature functional programming language. It was originally developed by Jordan Walke at Facebook and can target both JavaScript (via BuckleScript) and native code (via Reason Native). Its goal is to make OCaml more accessible to JS developers, both in syntactically but also when it comes to tooling. In this post we’ll explore how to write native CLI apps in Reason.| citizen428.net
If you often create new Rails apps, application templates can be a real timesaver. They have a very simple API, which allows developers to make changes to the Gemfile, execute Rails or Git commands, manage files and more. Here’s a simple template I use to generate a new Rails app with Devise already set up: gem 'devise' after_bundle do rails_command 'generate devise:install' rails_command 'generate devise User' end The first line adds Devise to the Gemfile and the after_bundle hook runs two...| citizen428.net
Coming to F# with almost no prior .NET experience can be a bit daunting, since one doesn’t only have to learn the language, but its entire huge ecosystem. So to get some experience on a bigger project I got myself a copy Jamis Buck’s excellent book The Ray Tracer Challenge and am slowly working my way through it. Due to the holidays, I didn’t get quite as far as I hoped yet, but you can follow along with development on the GitLab repository.| citizen428.net
In programming the term “literal” refers to notations for representing certain values in code. Almost all languages offer them for atomic types such as strings or various number formats, some also for compound types like arrays, records or hashes. Additionally lambda expressions are a literal representation of functions. Ruby has a rich set of literals for various use cases and in this post we’re going to explore some of the lesser known ones.| citizen428.net
In my ongoing efforts to learn F# properly, I recently stumbled upon the F# Data library, which implements type providers and other useful tools for working with data in CSV, HTML, JSON and XML formats. To try it out I hacked together a quick .fsx script which uses the library’s HTML parser to scrape the top three F# posts from one of my favorite programming websites, dev.to. Please note that the site does have an API, which would be the preferred way of doing this, the following is for dem...| citizen428.net
A couple of weeks have passed since my last post and I still really enjoy learning F#. So when I found this interesting post called “Emulator basics: a stack and register machine” in which the author builds a virtual machine for running simple C programs, I decided to port the code from EcmaScript. I won’t go into details regarding the actual VM design and its instruction set, the original post already explains it nicely.| citizen428.net
It’s no secret that I’m a big fan of functional programming languages. Being quite enamored with Ocaml I always wanted to get into F#, but its strong ties to the Windows ecosystem kept me from it for the longest time. However, this changed with the open-source release of .NET Core, so a bit less than a month ago I finally got serious about my F# learning. I’m mainly using The Book of F# (Amazon affiliate link), the F# for fun and profit website and the official documentation as learning...| citizen428.net
Docker’s multi-stage builds are an excellent way to reduce image size and I use them heavily in my Go projects. Today I realized that Crystal has a --static flag, which according to the documentation only works on Alpine Linux. I therefore decided to give a multi-stage build a try and compare it to other Docker approaches for Crystal. Here’s the admittedly not very exciting example program: # test.cr puts "Hello Docker world!| citizen428.net
bundler-audit is a small utility which can check your Gemfile’s contents against the Ruby Advisory Database. You can simply run it via bundle audit and it will report insecure gem sources as well as library versions that have known vulnerabilities: $ bundle audit Insecure Source URI found: git://github.com/compass/compass-rails.git Insecure Source URI found: git://github.com/sinatra/sinatra.git Name: nokogiri Version: 1.8.2 Advisory: CVE-2018-8048 Criticality: Unknown URL: https://github.co...| citizen428.net
I originally wrote this article for Codementor in October 2014. It should have something for everyone, from fairly new git users to experienced developers. 1. Discard local file modifications Sometimes the best way to get a feel for a problem is diving in and playing around with the code. Unfortunately, the changes made in the process sometimes turn out to be less than optimal, in which case reverting the file to its original state can be the fastest and easiest solution:| citizen428.net
I’m fascinated by Postgres: the more I learn about it, the more I realize how much I still don’t know. Recently I discovered its asynchronous communication capabilities, which apparently have been around for a long time ¯\(ツ)/¯ Let’s look at the two most interesting commands related to this topic, NOTIFY and LISTEN. Here’s what the documentation has to say on them: NOTIFY provides a simple interprocess communication mechanism for a collection of processes accessing the same Postgr...| citizen428.net
We all know the problem: different developers prefer different libraries, especially for their development workflow. However, for various reasons we may not just want to add them unconditionally to our application’s Gemfile: Added dependencies (including their own dependencies) for something that doesn’t directly relate to the actual app. Bikeshedding discussions about the virtue of gem A over gem B or why we should never use gem C 🙄 For this reason I generally add a Gemfile.| citizen428.net
Like many Ruby and Rails developers I use Pry instead of IRB for almost all of my projects. Recently I realized that many people are not aware of the fact that pry supports project-specific .pryrc files, which can come in very handy, for example when trying things out in a Rails console. Just add a .pryrc file at the root of your application and add code you want to be available in each console session there.| citizen428.net
This is a rather old post I originally wrote in 2013, but it’s still a good introduction to Lua and Nmap scripting, so I decided to repost it. Whether you are working as a security professional or a network administrator, chances are that Nmap (“Network Mapper”) is part of your regular toolkit. For many people this project, which was started by Gordon “Fyodor” Lyon in 1997, is the first choice when it comes to host and service discovery.| citizen428.net
For many years now Postgres has been my database of choice, but I still regularly find new and interesting features that I wasn’t yet aware of. The latest entry in this long list are “foreign data wrappers”, an implementation of the SQL/MED (“SQL Management of External Data”) specification which was added in Postgres 9.1. This mechanism allows for integrating our database with data stored outside of it. The most common use case for this is probably accessing a remote RDBMS (Postgres...| citizen428.net
I don’t know about you, but I can’t really remember the last time I added a bookmark to my browser (at least not on purpose, -D is right next to -F after all). So when I saw rustref.com, I knew I wanted to build something like this for the Ruby community, which is now available as rubyref.net. tl;dr RubyRef defines a list of CNAME records of the form *.rubyref.net which redirect to different Ruby related documentation sites.| citizen428.net
One thing I always liked about Smalltalk was the “Method Finder” available in several of its dialects. The following screenshot shows the version included in Pharo as an example: Essentially, this offers two different featues: Search for a method by (partial) name. Search for a method by example. By inputting a receiver, arguments (optional) and the expected result, one could find all methods that provide this functionality. In early 2009 I had started teaching courses at [RubyLearning](h...| citizen428.net
Search GitHub stars with Octokit and fzf If you are anything like me, you’re using Github’s repository stars as bookmarks for interesting projects you want to check out at a later date. And if you’re really like me (generally not advised) you love the command line and think it would be awesome if you had an easy way to search your stars from there. Today I had a spare hour, so I finally got around to build a solution that really fits my workflow, maybe it will appeal to you too.| citizen428.net
As promised in my previous post this article will cover some of the more advanced features of Crystal, namely macros, C bindings and concurrency. Macros When coming to Crystal from Ruby, one of the biggest changes is the lack of runtime introspection that enables much of Ruby’s metaprogramming techniques. However, this can be rectified to a certain degree by using macros, which are methods that receive AST nodes at compile time which they use to write new code.| citizen428.net
Disclaimer: the good folks at No Starch Press were kind enough to provide me with a review copy of this book, but this did not influence my assessment in any way. The Manga Guide To Regression Analysis (affiliate link) is No Starch’s latest addition to the popular Manga Guide series which so far consists of 12 books covering different topics in science and mathematics. Not surprisingly the series is originally from Japan, where it is published by Omsha.| citizen428.net
Currently there’s no shortage of new and interesting programming languages. It almost seems impossible to spend any time on Hacker News or Twitter and not see announcements of new languages on a weekly basis. Being a huge programming language nerd I generally read up on most of them, but few manage to hold my interest for long. Crystal however is one new language that did and the tag line on their BountySource page sure contributed to that:| citizen428.net
There are not many things that programmers enjoy more than arguing about definitions. So it’s no wonder that terms like “functional programming” can have different meanings for different people. However, all the definitions I came across so far included that functions need to be “first-class”, i.e. they are no different from other basic data types (like numbers or strings) in that they can be stored in variables, passed as arguments, or returned as another function’s result.| citizen428.net
Of closures and objects A couple of months ago one of my coworkers posted the following little koan (source) in our Slack chat and mentioned that he himself has not yet attained enlightenment: The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said “Master, I have heard that objects are a very good thing — is this true?” Qc Na looked pityingly at his student and replied, “Foolish pupil — objects are merely a poor man...| citizen428.net
My blog gets generated with Hugo, which I’m generally happy with. Until recently, I hosted the static files on Netlify but now decided to get my own little server again. There are two main reasons for this: I actually missed doing some sysadmin work. The Internet was supposed to be a federated system and I don’t want to outsource everything to a few tech giants. Operating system choice OpenBSD has always been one of my favorite (server) operating systems, for reasons that are nicely summa...| citizen428.net