Detecting variables that are mistakenly or unknowingly added to the
global scope can be helpful to debug your apps and avoid naming
collisions. The more a web app and its dependencies grow, the more
having a good understanding of what’s happening in the global scope
becomes important (e.g., to ensure multiple libraries — or even
multiple apps! — can coexist on the
page without global name collisions).
It's an article of faith in many quarters that you shouldn't write
anything much as a shell script and should instead use a proper
programming language. I generally agree with this in theory, but
recently I went through a great experience of why this doesn't
necessarily work out for me in practice, as I wrote (and then
rewrote) a shell script that really should be a program in, say,
It is now widely known that Ubuntu 22.04 LTS (Jammy Jellyfish) ships
Firefox as a snap, but some people (like me) may prefer installing
it from .deb packages to retain control over upgrades or to keep
I was recently exploring how to get a local backup of WhatsApp
messages from my iPhone. I switched from Android to iOS in the past
and lost all of my WhatsApp messages. I wanted to make sure that if
I switched again from iOS to Android I don’t lose any messages. I
don’t really care if I can import the messages in WhatsApp. I just
don’t want to lose all of the important information I have in my
chats. I don’t have any immediate plans for switching (if ever) but
it seemed like a fun challenge and so I started surveying the
available tools and how they work.
This was mostly a learning exercise for me regarding how Apple
stores iOS backups and how I can selectively extract information and
data from one. My target was to have a local copy of WhatsApp
messages that I can read and search through locally. It would be
doubly awesome if I can move the messages to an Android device but,
as I mentioned before, that wasn’t my main aim.
one of my favorite design patterns to develop highly-testable and
modular code. To apply this pattern, all you have to do is follow
two simple guidelines:
Separate object construction from usage. In practical terms: stop
creating objects inside constructors and take those objects as
Use interfaces instead of concrete types as constructor
parameters. In this way, the receiver remains agnostic to the
implementation of those types and thus it becomes possible to
supply different implementations.
I've ended up with a testing process that will run the dotfiles
setup and test that the script has performed specific behaviours
such as creating files and symbolic links or checking that packages
were installed properly. All of this runs as a CI process on GitHub
actions using Test Kitchen and InSpec.
Memray is a memory profiler for Python. It can track memory
allocations in Python code, in native extension modules, and in the
Python interpreter itself. It can generate several different types
of reports to help you analyze the captured memory usage data. While
commonly used as a CLI tool, it can also be used as a library to
perform more fine-grained profiling tasks.
In these days of web apps and REST APIs it seems that writing
parsers is a dying art. You may think parsers are a complex
undertaking only reserved for programming language designers but I’d
like to dispel this idea. Over the past few years I’ve written
parsers for JSON,
CSS3, and database query
and the more that I write parsers the more that I love them.
The diff3 conflict resolution strategy is a hidden gem in git that
has saved me uncountable conflict-resolution headaches and has
turned git conflict resolution into something of a joy for
me. Weird, I know!
It turns out that some recent releases of Java were vulnerable to a
similar kind of trick, in the implementation of widely-used
signatures. If you are running one of the vulnerable versions then
an attacker can easily forge some types of SSL certificates and
handshakes (allowing interception and modification of
communications), signed JWTs, SAML
or OIDC id
and even WebAuthn authentication
messages. All using the digital equivalent of a blank piece of
accumulating a large number of concatinations. As a Java programmer,
that came as a shock to me. This article summarizes my exploration
of this fact.
Message is one of the most popular messaging
today, largely because it is built into iOS and Mac devices. Since
its release, it has evolved significantly. But, at its core, it is
simply an instant messaging platform. iMessage uses SQLite in the
background to store relational data about messages, conversations,
and their participants.