Accessing Private Fields During Object Construction in JavaScript
I was writing some JavaScript using the new-ish class syntax, and I ran into a gotcha. Consider the following code:
I'm a software engineer living in Louisville, Kentucky.
I make video games at Two Scoop Games,
volunteer at Louisville Makes Games,
and help organize the local tech scene at LouisvilleTech.org.
I work primarily with JavaScript, React, Elixir, Node.js, and Ruby.
I was writing some JavaScript using the new-ish class syntax, and I ran into a gotcha. Consider the following code:
I had a bout of insomnia last night, and I imagined a little programming exercise to write a function that would take an integer and translate it to the english words for that number. I felt that Elixir's pattern matching and macros would make the resulting code small and beautiful.
I often need to view a bunch of static HTML files in my browser locally, and I
often need to open them with http://
rather than file://
URLs so related
CSS or JavaScript files load correctly. Luckily, Python provides a simple web
server, and most Linux distros include Python.
I have a recurring problem in Ubuntu where my /boot
partition fills up with
old kernels, so I can't run updates to get new kernels. I've never really found
a satisfactory fix, so I wrote up a bash script to help me.
I use IO.inspect/2
all the time
when I'm debugging something, and I often run into a problem where I'm looking
at a gigantic map with lots of fields that gets truncated. I usually want
everything to be printed, and I have to remember the options to enable it. So
for reference for my future self, here's a handy function that actually prints
everything:
Since most places are renaming the default git branch from master
to main
I
want to do the same to reduce friction. I want to rename all my default branches
in all my projects in one afternoon so I can retrain my muscle memory and not
have to remember which project uses which branch name.
Working as a programmer today you end up writing a lot of plumbing code, gluing together systems under your control with external systems. Many times you have to build processes to ingest data from other companies. Sometimes you pull the data, either querying an HTTP API, downloading CSV files from an FTP server, or even directly connecting to a partner's database. Other times, data is pushed to you, either through your own API, webhooks, or a shared S3 bucket.
My game Kick Bot uses Cinemachine to control Unity's cameras. Cinemachine lets you create multiple virtual cameras, and the real Unity camera will focus on the one with the highest priority. The priority is just an integer you can change with code whenever you want. When a new virtual camera becomes the "live" camera, Cinemachine will perform a blend from the old camera to the new one. Cinemachine will also let you create a blend list specifying blends in between specific virtual cameras.
Idempotence is the property of a software that when run 1 or more times, it only has the effect of being run once. I'll describe a process I'm making at work, and describe the problems that idempotence will help avoid.
Like a lot of people, I hate advertisements. In my quest to remove ads as much as possible, I've installed an ad blocker in my browser. To go further, I've installed Pi-Hole to block ads for all devices on my home network. I've even setup firewall rules to re-route all DNS traffic through Pi-Hole. This setup seemed to work pretty well until I noticed I was still seeing ads in an app on my Android phone.
I'm a big fan of RSS. I'm up to 155 feeds in my favorite RSS reader. That means I read lot of news, blog posts, etc. A lot of it is mildly interesting, but there's a few links each week that stand out. These "interesting links" are either really thought-provoking, give me a "light bulb moment", capture my imagination, or are extraordinarily relevant to one of my interests/hobbies.
If you have a web site that shows dates and times, it can be confusing to people reading the site if they are displayed in a different time zone than what the person uses. With a little bit of JavaScript and the Luxon date library you can format your dates into the viewers local time zone.
I got a neat desk-mounted macro pad called the
Pikatea. I wanted one of the buttons to cycle my
computer's audio output between my headphones and speakers. I found that you can
use pactl
to
inspect PulseAudio settings, and change them. Below is a bash script I wrote to
cycle output (i.e. "sinks" in PulseAudio terminology). You can run it multiple
times, and it'll pick the next output after the current one.
I decided to try out tmux
's mouse mode by adding set -g mouse on
to my
~/.tmux.conf
file. It is really nice being able to select and resize panes
just by clicking on them. One thing I didn't expect was that when you have two
vertical split panes, that dragging your mouse to select text would wrap
correctly and only select text in a single pane! I had to add this command to my
~/.tmux.conf
to make it automatically copy to the system clipboard:
I installed some old hard drives into my server to get some files off them. They
were a RAID 1 array, using LVM and encrypted with LUKS. It was confusing to
figure out which /dev
entries belonged to what, and in what order
RAID/LVM/LUKS was setup. After some searching I found the lsblk
command which
gives a nice visual layout of how the devices are laid out:
I believe privacy is a fundamental human right, and I set up technology to help enforce my privacy on the internet. I use Firefox as my web browser because it's open source and not run by an advertising company. A web browser is a user agent, meaning it works for the user. Here are the settings I configure to help me be private on the web.
I was watching some videos from the Home Assistant Conference, and I learned a few things about the Home Assistant Android Companion App.
I wrote Living in Syndication to scrape websites and generate missing RSS feeds. I was having trouble with a certain site rate-limiting my scraping to something ridiculous like 5 requests per day! It's not like I'm hammering the site or doing anything unethical.
I've recently rediscovered the joys of RSS thanks to a RSS reader called Miniflux. RSS lets you subscribe to websites and automatically get notified when new content is available. RSS is a pull technology, meaning you control how often you check for content, can unsubscribe whenever you want, and don't have to give any information to the content provider. RSS has the usability benefit of making it easy to consume lots of information from many places very quickly.
I recently built a Pi-KVM machine so I could access the BIOS settings of a server in my basement remotely.
I want to convince you to self-host as many internet services as possible. Self-hosting a service means installing and running software on a computer you control. You can self-host out of your home or a rented computer in the cloud.
The recent news of youtube-dl being taken down from GitHub due to a DMCA takedown notice from the RIAA provides a good reminder that you should maintain backups of any software that you depend on.
I'm working on a project where I'm building an Elixir
Phoenix website to take over specific paths
on a larger website. The sites are hosted on AWS, so my plan is to use an ELB
with Listener
Rules
to send requests for specific path prefixes like /news*
to my Phoenix server,
and send any remaining paths to the old server.
This is a lightning talk I gave at Louisville Makes Games on Thursday, November 14th.
I was fortunate enough to attend ElixirConf 2019, and I wanted to give a list of my favorite presentations I saw while there.
After showing a game at a trade show/gallery/festival, I've noticed a problem where people walk away from a game mid-session. This makes it so the next person to walk up will start the game half-way through and miss the beginning, which often includes tutorials or learning moments. To make sure a demo restarts, I wrote this Unity script that fires an event when no inputs have been received for a set amount of time:
Alex, Jake, and I travelled to Chicago this weekend to show off Kick Bot at Bit Bash Chicago.
I'm going to be showing off an early build of Kick Bot, a game I've been working on for a long time, at Bit Bash Chicago this weekend. If you're in the area, stop by and say "Hi"!
Louisville Makes Games, a non-profit I'm on the board of, was recently written about in the local newspaper: Louisville gamer startup is changing the negative stereotypes around video games. The article was also cross-published in USA Today.
At work we have an ASP.NET web site that uses the built-in ASP.NET SqlMembershipProvider. My task was to enable one of our Elixir apps to authenticate users using their credentials used in the ASP.NET app.
Many modern JavaScript development tools are distributed through NPM and tell you to install them globally. For some packages it is okay to install them globally, but other packages are creating a future headache for you. I will explain the problem with global NPM packages, how to tell when it is okay, and how to use locally installed packages instead.
CSS makes up the majority of code responsible for implementing a responsive web site. Every once in a while I come across certain aspects of a responsive site that can only be implemented with JavaScript. In order to avoid repeating the screen widths (once in CSS, once in JavaScript), my coworker Martin Hofmann and I came up with a way of detecting the current CSS breakpoint from JavaScript.
I ran into a head-scratching problem with a pure React component where it was re-rendering when it shouldn't. The component wrapped up a 3rd party script which put a button on my site. The problem was that when the button was clicked, some of my state changed so I could show a loading spinner. That state change made my component re-render, which broke the 3rd party script by re-initializing it.
This is a presentation I gave at JSLou on Wednesday, February 15th, 2017. Sorry, but the audio cuts out in a few parts of the video.
This is a presentation I gave at JSLou on Wednesday, August 17th, 2016.
Whether you're going to build a real life social network by organizing a new meetup, or begin attending one, this is a list of common technology meetup formats.
HTML5 gave life to new JavaScript APIs that make it possible to create amazing game experiences on a web page. Learn how to draw on a canvas, make sounds, respond to input, then how to package the game and ship it on the Apple App Store and Chrome Web Store.
In today's modern web development, much of a programmer's productivity comes from code that they did not write themselves. Much of that code is hosted on GitHub, and less and less of it has any amount of documentation. The most prominent form of documentation is now the README.md file in the project's root.
A few months back I was volunteering at Code Louisville and helping George log into a forum. He had signed up a few days ago, but never logged in. When he tried to log in, the forum gave an invalid username or password
error. George had unknowingly created a Schrödinger-ed user account.
I'm interested in the quantified self and I wanted to log data about my car and how I drive. I'm also concerned about privacy, and wanted to keep my data private and not rely on a company or service. Since I already had a Android smartphone, I was able to put together a fully automated system for only about $35!
One of my favorite parts of Git is how it lets you fix your mistakes. One mistake I needed to fix a few times in the last year was having two separate repositories, when they ought to be a single respository. I will present commands to merge a child repository into a parent respository as a subdirectory. The new child repository subdirectory will preserve its history and look like it was always part of the parent repository.
Building a real social network is easier and more rewarding than building the next Facebook or Twitter. Even shy, introverted programmers (such as myself) can build a powerful network in just a few months. The relationships you build will keep you excited, up-to-date, and alter the trajectory of your career. You can't afford to stay home.
While I was out to dinner last night I decided to pick up a movie on the way home. I opened up my RedBox Android app, and tried to make a reservation. The experience was more frustrating than it needed to be, so I wanted to document the problems with the app's UI in the hopes that they are fixed, and so others do not make the same mistakes.
This weekend I gave a presentation on the Jekyll static site generator at MOSSCon.
I've wanted to switch my email program to Mozilla Thunderbird for a while, but I always gave up when trying to import my old mail. My old email client used the MH mail format, which Thunderbird cannot easily import. Luckily, I found a blog post that describes how to use the packf command to convert MH email to the MBOX mail format that Thunderbird uses.
I've spent a lot of time last year learning my tools better, and I've built up a list of plug-ins for Visual Studio that help me work smarter and faster. All of the plug-ins below work on both Visual Studio 2010 and 2012.
One of the coolest parts of Git is that once you learn it, you will never need to use another VCS. My company uses Perforce for version control, and it can be painful. So when I got to work on a new greenfield project, I stuck everything in Git. That worked great for a few weeks until I needed to begin collaborating with other developers who would only use Perforce. Fortunately, Git has a Python script that lets you interact with Perforce servers using a special "git p4" command set. The tricky part is getting it all set up on Windows where Git and Python are out of their normal Unix environment.
Back in November I was able to attend the Software Craftsmanship North America conference in Chicago. I signed up for the post-conference Code Retreat, which sounded like a fun day of writing code with my peers. During the conference I met many awesome people, including Mike Clement. Mike told me about the upcoming Global Day of Code Retreat on December 8th. Mike said he was going to run a session in Utah, and persuaded me to run one in Louisville.
Other people's content that I found interesting and I think is worthy of sharing.