Aaron Christiansen's Avatar

Aaron Christiansen

@aaronc.cc.bsky.social

Software Engineer at ETAS Ruby, Rust, and electronics Leeds, UK - he/him Mastodon: @aaronc81@ruby.social

55 Followers  |  207 Following  |  41 Posts  |  Joined: 09.11.2024  |  2.0449

Latest posts by aaronc.cc on Bluesky

Preview
Ruby argument validation with pattern matching

Ruby argument validation with pattern matching

aaronc.cc/2025/12/12/r...

12.12.2025 00:20 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

Starting to get interesting - now you can write operator modules which behave based on some properties of their children - here repeating the children in a grid.

You can't do something like this in OpenSCAD unless you also pass a separately-calculated size for the children.

30.11.2025 01:40 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
A code editor showing an STL preview with a small cube on top of another big cube. The code beside is:

```
// Create an object and make a binding for it
big_cube = cube([20, 20, 20]);

// Reference that binding to create another object
translate([0, 0, big_cube.size.y])
cube([5, 5, 5]);
```

A code editor showing an STL preview with a small cube on top of another big cube. The code beside is: ``` // Create an object and make a binding for it big_cube = cube([20, 20, 20]); // Reference that binding to create another object translate([0, 0, big_cube.size.y]) cube([5, 5, 5]); ```

Having a crack at a project I've been thinking about for a while. An OpenSCAD-alike where you can introspect objects you've already drawn - which means less thinking about how to structure your variables for quick thrown-together 3D prints. First prototype works well!

28.11.2025 22:28 β€” πŸ‘ 3    πŸ” 0    πŸ’¬ 0    πŸ“Œ 1

Inline RBS feels like something Ruby 3 needed from the beginning, and now that it’s here it looks really exciting!

Need to find some time to play with it and see how it actually feels to use…

12.11.2025 16:20 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

I read a lot of physical magazines when I was younger - Linux User & Developer, NET, The MagPi - and enjoyed the layouts too. You can get a bit creative with your page in a way that’s harder with an online blog that needs to support different device sizes

09.11.2025 14:19 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Online blogs are great, with a lot of quality content nowadays, but I struggle to actually find new stuff.

Aggregators like HN/Lobsters/Reddit only show you a title. Feed-based socials are too noisy

Magazines make you flick past everything, and you might catch a glimpse of something interesting

09.11.2025 14:19 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Preview
Paged Out! Deeply technical zine. And it's free.

I found out about the β€œPaged Out!” Magazine, which publishes one-page articles about programming and computing. I absolutely LOVE this

pagedout.institute

09.11.2025 14:19 β€” πŸ‘ 4    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
The 3D-printed macro pad, now with a thick base plate with a cutout for a USB port, and grey keycaps fitted.

The 3D-printed macro pad, now with a thick base plate with a cutout for a USB port, and grey keycaps fitted.

With the 3D-printed base added, and some spare "retro" keycaps, it's good enough for me to call it done!

On the software side, it only needed some little tweaks to support the extra three keys, and swap to active-low because it made the wiring easier.

02.11.2025 23:36 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
A 3x3 grid of mechanical keyswitches on a black 3D-printed plastic plate, with a blank space above them

A 3x3 grid of mechanical keyswitches on a black 3D-printed plastic plate, with a blank space above them

The other side of the plate, with wires connected from the switches to a Raspberry Pi Pico microcontroller screwed into the plate

The other side of the plate, with wires connected from the switches to a Raspberry Pi Pico microcontroller screwed into the plate

Next day update: I tried to route wires between the switches and Pico, but couldn't figure out anything I was happy with.

So I remade the plate to have the Pico integrated, which made the wiring much easier!

The blank space doesn't look too great, but I can always vinyl-cut something to go there

02.11.2025 20:32 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
    let keys_future = async {
        loop {
            let selected = select6(
                f13_pin.wait_for_high(),
                f14_pin.wait_for_high(),
                f15_pin.wait_for_high(),
                f16_pin.wait_for_high(),
                f17_pin.wait_for_high(),
                f18_pin.wait_for_high(),
            ).await;

            let code = 
                if      selected.is_first()  { KEY_F13 }
                else if selected.is_second() { KEY_F14 }
                else if selected.is_third()  { KEY_F15 }
                else if selected.is_fourth() { KEY_F16 }
                else if selected.is_fifth()  { KEY_F17 }
                else if selected.is_sixth()  { KEY_F18 }
                else { panic!() };

            info!("Pressing key: {}", code);

            writer.write_serialize(&KeyboardReport {
                keycodes: [code, 0, 0, 0, 0, 0],
                ..KeyboardReport::default()
            }).await.unwrap();

            Timer::after_millis(50).await;

            writer.write_serialize(&KeyboardReport {
                keycodes: [0, 0, 0, 0, 0, 0],
                ..KeyboardReport::default()
            }).await.unwrap();
        }
    };

let keys_future = async { loop { let selected = select6( f13_pin.wait_for_high(), f14_pin.wait_for_high(), f15_pin.wait_for_high(), f16_pin.wait_for_high(), f17_pin.wait_for_high(), f18_pin.wait_for_high(), ).await; let code = if selected.is_first() { KEY_F13 } else if selected.is_second() { KEY_F14 } else if selected.is_third() { KEY_F15 } else if selected.is_fourth() { KEY_F16 } else if selected.is_fifth() { KEY_F17 } else if selected.is_sixth() { KEY_F18 } else { panic!() }; info!("Pressing key: {}", code); writer.write_serialize(&KeyboardReport { keycodes: [code, 0, 0, 0, 0, 0], ..KeyboardReport::default() }).await.unwrap(); Timer::after_millis(50).await; writer.write_serialize(&KeyboardReport { keycodes: [0, 0, 0, 0, 0, 0], ..KeyboardReport::default() }).await.unwrap(); } };

…and a little Rust program for the Pi Pico, using Embassy to send keypresses for F13-F18 when pins change.

Embassy makes USB device implementation pretty straightforward πŸ¦€

01.11.2025 21:50 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Six Gateron Brown key switches inserted into a black plastic plate, with jumper wires coming out the back

Six Gateron Brown key switches inserted into a black plastic plate, with jumper wires coming out the back

Seeing if I can put together a tiny macro pad to live in my work’s office - I miss my macros when I’m not working from home!

First steps - a 3D-printed plate with hardwired Gateron Browns (with jumpers I now realise I’ve made far too long)…

01.11.2025 21:50 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
THE TWILIGHT SAD - WAITING FOR THE PHONE CALL
YouTube video by thetwilightsadofficial THE TWILIGHT SAD - WAITING FOR THE PHONE CALL

New Twilight Sad, wooo! Fantastic start, can't wait for more...

www.youtube.com/watch?v=P9zu...

28.10.2025 18:15 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

My Jujutsu problems were caused by .gitignore being case-sensitive. Turns out I've been relying on case-insensitivity for a long time - macOS and Windows will do that to you ;)

Patched in case-insensitivity, and now Git and Jujutsu agree with each other: github.com/AaronC81/jj/...

25.10.2025 09:32 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

I’ve landed a little warning improvement in this release! Gleam was a lovely codebase and community to contribute to - high hopes for where this language goes in the future

20.10.2025 10:24 β€” πŸ‘ 6    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

The β€œfun”/hash-rocket approach does look nice, but I think the discoverability to IDEs/YARD/etc of the chosen approach is worth it!

I’ve toyed with Literal before and enjoyed using it - excited to give this feature a go one day :)

20.10.2025 10:19 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

🀯 Absolutely love this

I’ve experimented with similar, but never figured out how to make default values play nicely with the annotations, or how to represent return types. This approach looks really elegant!

20.10.2025 09:20 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Windows 95 UI mockup.

"Add 3D Printer Wizard" 
Windows can print physical objects by sending G-code
to a 3D printer.

This wizard will help you to install your 3D printer.

To begin, select how the printer is connected to your
computer.
The printer is connected using a serial cable.
The printer is connected using a parallel cable.
The printer is connected to another computer on my network.

Windows 95 UI mockup. "Add 3D Printer Wizard" Windows can print physical objects by sending G-code to a 3D printer. This wizard will help you to install your 3D printer. To begin, select how the printer is connected to your computer. The printer is connected using a serial cable. The printer is connected using a parallel cable. The printer is connected to another computer on my network.

Of course, 3D printing caught on quickly, so Microsoft added native support for connecting a 3D printer to your computer

16.10.2025 23:33 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
A UI mockup of Ultimater Cura running on Windows 95. In the centre is a greyscale render of a Benchy on a 3D print bed. The left-hand panel includes dropdowns to select printer, nozzle, and filament settings. Underneath are print properties like a layer height profile, infill slider, support checkbox and adhesion checkbox. Under the render is an object selection list box, with toggle buttons for render controls.

A UI mockup of Ultimater Cura running on Windows 95. In the centre is a greyscale render of a Benchy on a 3D print bed. The left-hand panel includes dropdowns to select printer, nozzle, and filament settings. Underneath are print properties like a layer height profile, infill slider, support checkbox and adhesion checkbox. Under the render is an object selection list box, with toggle buttons for render controls.

What if we were 3D printing decades ago? Downloading STLs over dial-up?

I mocked up Cura for Windows 95

15.10.2025 18:31 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 2    πŸ“Œ 0

After a few days - this works alright!

Only issue is there's some disagreement between Git and Jujutsu about a few files from LFS - Git is tracking them, but Jujutsu thinks they're new.

If I delete them, Git sees the repo as dirty, but Jujutsu is happy and works a treat.

09.10.2025 18:05 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 1

No support yet for submodules and LFS limits how much I can use it, sadly, but I’m keen to see whether I can just ignore all that stuff in Jujutsu and fall back to Git’s CLI instead

04.10.2025 18:16 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 1    πŸ“Œ 1

Having a play with Jujutsu VCS: jj-vcs.github.io/jj/latest/

You can move back to a previous commit and edit it, and all the later commits rebase automatically… coming from Git, that feels MAGIC

04.10.2025 18:16 β€” πŸ‘ 2    πŸ” 1    πŸ’¬ 1    πŸ“Œ 0
A screenshot of Apple Photos on iOS showing β€œMagdalena Bay Concert” as a tag

A screenshot of Apple Photos on iOS showing β€œMagdalena Bay Concert” as a tag

I don’t know how long this has existed, but I’ve never spotted it before… Apple Photos smooshing together geotagging and event listings to give concert photos an artist tag - which you can search by! - is such a damn clever feature

22.09.2025 20:54 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

all the best windows software in history is called something like "joe's thing doer". it does the thing and nothing else and is available on a html website in plain text and takes up under a megabyte of space and uses default windows ui elements and will work until the heat death of the universe

31.08.2025 21:53 β€” πŸ‘ 8040    πŸ” 1917    πŸ’¬ 182    πŸ“Œ 98

This looks really promising - I’ve read a lot of praise for uv in Python-land, so having something similar on the horizon for Ruby is exciting

andre.arko.net/2025/08/25/r...

26.08.2025 21:37 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
A screenshot of Echo Point Nova. Looking from a height over a dense forest, surrounded by water, with snowy mountains in the distance. Checkpoint markers are visible as tall blue and orange streaks of light are visible, sprinkled across the world.

A screenshot of Echo Point Nova. Looking from a height over a dense forest, surrounded by water, with snowy mountains in the distance. Checkpoint markers are visible as tall blue and orange streaks of light are visible, sprinkled across the world.

Echo Point Nova is one of my favourite recent indie games, a super fast movement-shooter, and the first game in a while I’ve 100% completed

…and it just got an entire second map as a free update. Time to 100% complete this too 😁

23.08.2025 20:28 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

Yep, the argument order must be the same as the definition, unlike many languages' keyword arguments

I'd guess this is from Objective-C heritage where methods don't have names, but are identified by the keyword arguments...?

If an argument is defined with a default value, you can omit it on a call

22.08.2025 22:40 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
Apple Developer documentation for the method β€œreplacingOccurrences(of:with:)”.

Returns a new string in which all occurrences of a target string in the receiver are replaced by another given string.

func replacingOccurrences(
    of target: String,
    with replacement: String
) -> String

Apple Developer documentation for the method β€œreplacingOccurrences(of:with:)”. Returns a new string in which all occurrences of a target string in the receiver are replaced by another given string. func replacingOccurrences( of target: String, with replacement: String ) -> String

I enjoy using keyword-argument-heavy languages, and IMO an underappreciated feature is letting arguments have different external vs internal names.

An example in Swift - variables named β€œof” and β€œwith” would be unintuitive inside the function body, but read naturally when calling

22.08.2025 19:21 β€” πŸ‘ 4    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Preview
Propeller 2 - Parallax Multicore Specs

I suddenly remembered the Parallax Propeller - a microcontroller with a custom architecture and language, which I saw mentioned on Arduino forums back in the day and thought looked super cool.

Turns out they released a second generation a few years ago! Awesome…

www.parallax.com/propeller-2/

17.08.2025 18:14 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
import gleam/io

fn twice(f: fn() -> Nil) {
  f()
  f()
}

pub fn main() -> Nil {
  use <- twice()
  io.println("Hello!")
}

// Prints:
//   Hello!
//   Hello!

import gleam/io fn twice(f: fn() -> Nil) { f() f() } pub fn main() -> Nil { use <- twice() io.println("Hello!") } // Prints: // Hello! // Hello!

And of course, like any good language feature, you can use it for Funky-Looking Shenanigansβ„’

05.08.2025 21:30 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
import gleam/io

pub fn defer(deferred: fn() -> Nil, body: fn() -> t) -> t {
  let return_value = body()
  deferred()
  return_value
}

pub fn main() -> Nil {
  use <- defer(fn() { io.println("All done!") })
  io.println("Main function body")
}

// Prints:
//     Main function body
//     All done!

import gleam/io pub fn defer(deferred: fn() -> Nil, body: fn() -> t) -> t { let return_value = body() deferred() return_value } pub fn main() -> Nil { use <- defer(fn() { io.println("All done!") }) io.println("Main function body") } // Prints: // Main function body // All done!

You could also use this for resource management, like deferred finalisation.

Gleam doesn't have early returns, so you don't need to worry about that skipping your clean-up.

05.08.2025 21:30 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

@aaronc.cc is following 19 prominent accounts