In a code review that I did today, I left a final note to the author of some new piece of code:
Sorry for nitpicking on code naming. The approaches you take are good, but naming is hard (but important!):
> There are only two hard things in Computer Science: cache invalidation and naming things.
(see here a list of variations on these two hard problem 'jokes' in Computer Science)
I enjoy the ruby programming language because you can get a long way by just assuming things. A collection implements each
, every object has nil?, in rails, I can get the relationship of a record and use scopes to filter the relationships as defined in the class of that related record. If it ands with a questionmark, it returns a boolean(y). Anyway.
So while they might say: "never assume things", and sure, a lot of things are chaos, but ideally not our code base :) I prefer to work from assuming t…
Sometimes I get confused by terminology. And many of the marketing pages that reply to such queries don't really help. So I here is my simple breakdown of these terms in relation to each other.
Entitlements are Granular Permissions. Entitlements represent specific rights or privileges and are the building blocks of roles and can be assigned individually or as part of a role.
Example: An entitlement might be "Access to Premium Reports". This entitlement can be part of multiple roles, such as "Admin" or "Premium User".
Note that not always entitlements are explicitly exposed, and are roles used in downstream applications to determine the exact entitlements associated with a role. Enterprise applications do attempt to separate these, but there is a lot of additional administration associated with this, especially when applications are extended rapidly.
Can be considered a collection of entitlements, a higher-level abstraction that groups m…
It is good practice to leave your database in a consistent state. There are different ways to do this. Foreign key constraints, indexes, typing of columns, are all strategies to keep your database in a consistent state. Transactions are another way providing you a tool to keep the database consistent: if one of the inserts or updates fail, your database will rollback to the state before the first in the series of inserts and updates within that transaction.
Some languages make it really simple to create a transaction. In Ruby on Rails it is simply opening a block:
User.transaction do
## ... all db operations are now in a transaction
end
But be cautious; transactions don't come for free: they lock the table or row, which is bad for performance. It can, by design, stop other processes from updating the same rows. And all this gets worse when transactions take longer, when for example they contain request to remote resources.
Hence, my approach to transact…
I'm fond of data-URI's (MDN Link). 12 years ago I reappropriated a tool that stored a webpage with its related resources in a Microsoft specific format and rewrote it into something that would store it in normal HTML where the related resources were encoded in data URI's. Recently the topic came up again at a project I was working in, where microservices are still a thing. And while discussing it with colleagues it seemed as if knowledge about this quite useful URI-scheme wasn't on top of everyone else's mind. Instead, the original idea was, we could upload the resource to S3, pass the link, download the resource from S3 at the receiving end, and then have some policy that takes care of deleting it… nah…
This is the most simple data-URI:
data:,Hello%2C%20World%21
You [can open it in your browser](dat…
If you're into archival stuf, you've probably come across the concept of PIDs. PIDs help organisations attribute data to consistently identified objects. There are different PID-schemes. Books can be persistently be identified by their ISBN. In science, DOIs are popular to identify scientific articles. And there are plenty of other persistent identifiers.
What most of them share is the following: they need registration. And while that could be a good thing, I've seen well meant attempts at creating a PID where the central entity went rogue, links are dependent on some centralised resolver and it all falls apart.
When I was tasked to create a long lasting QR label the requirements were clear:
Are you sure?
Decorators decorate your class with new set of functionality.
What are your decorators doing? Adding a few rendering specific methods to a class to help with rendering? Perhaps you should consider Presenters. But better: how will it scale, can it be grouped, will it really add the simplification. Be wary of too quick branching off functionality to decorators. Most cases I've seen them were overly architectured, and they didn't bring much value.
One might consider using Concerns or mixins as an alternative. The disadvantage here is that your main object gets more public methods, but I consider it as a feature after having experienced too much potentially reusable functionality grouped arbitrarily away in other presenter / decorator classes.
I'm quite familiar with writing ruby code. I've even expressed my love for the language long time ago. But some constructs still bug me. One of them is unless…
I've seen variants of this code:
temperature = 36.7
unless temperature > 37.2 || temperature 35.5 && temperature < 37.2
puts "Healthy temperature. Temperature is within the normal range."
end
or perhaps even nicer:
if (35.5...37.2).include?
puts "Healthy temperature. Temperature is within the normal range."
end
I'm not a data recovery specialist, but I tend to help people out every now and then with computer problems, and sometimes you have to deal with a disk that doesn't seem to work anymore. This is a collection of notes I made after I got a new challenge. I had to resort to using testdisk and ddrescue. I've been testing a few tools, and read about more, but these were the tools I landed on.
IMPORTANT: I'm not an expert on this topic. Every additional moving of the needle can cause a harddrive to fail even harder. If your data is absolutely critical, use a certified data recovery service.
When I get a harddrive in a laptop or external enclosure, my first attempt is to see if there is something between computer and the disk. I try to remove the disk from the computer or enclosure and connect it to a USB3 to 4-types of P/SATA adapter I have bought years ago and has saved me multiple times. If it mounts, copy everything to another drive, to b…
Veel inspirerende en mooie woorden dit jaar op PublicSpaces Conferentie 2024, maar vrij van zorgen was ik erna niet. Op de tweede dag sprak Bert Hubert uit in een jolig pessimistisch verhaal dat hij er vanuit gaat dat over enkele jaren 98% van de e-mails verzonden wordt vanuit dan wel servers van Microsoft dan wel Google. Ik hoopte na de PublicSpaces conferentie terug te gaan met nieuwe moed en handgrepen een kleine bijdrage te kunnen leveren om deze beweging te kenteren, maar desillusie is het gevoel dat me beklijft. Misschien moeten we hoop hebben dat de uit de DMA act volgende aanscherping van de aanbestedingsregels helpt om te voorkomen dat de grote partijen niet alles op kunnen slikken, zoals Kim van Sparrentak (MEP voor GroenLinks, voor wie ik eerder een positief stemadvies gaf) aangaf. Maar terwijl [Amsterdam trots aankondigt bezit te zijn met een "autonome strategie"](https://a…
For projects I maintain, I try to keep dependencies up to date on a regular basis. But not all people work like that, some live by the adage of "if it ain't broken don't fix it", but that is not an approach I subscribe to in software development.
A common reason to update software dependencies is to fix security issues or bug fixes that plague the project at hand. My main argument in favour of making more frequent updates is that when you suddenly need to make an update (because of an imminent security threat) it won't be hard; when dependencies haven't been updated in a long time it can be hard to to make the update.
There are risks involved in updating dependencies: A new version might introduce breaking changes, things that you rely on suddenly don't work or exist anymore. It might even introduce new bugs that may not be apparent on the first run. And when your test suite is not on par, verifying if everything works as expected is time consuming. But that can all be address…
There are a few hard problems in computing. Correctly handling time, naming, preventing off by one errors… sorting text may not be one of them but recently we ran into a discussion where I couldn't make up my mind anymore. Hence, this post's topic: sorting text.
How do you sort the following words:
If you'd ask ruby I'd get:
%w[cheese Ape Drums dent Beer].sort
Results in:
Which in my useless and ramshackle programmer's brain translates to, well why not, it is sorted right?
But then we moved the data into a database which was correctly set up with a proper locale for 'collation', a term that I've seen but never meant anything to me until this problem. Collation is:
> the assembly of written information into a standard order.
(thanks Wikipedia - Collation)
Databas…
I was asked to make a list of my favourite beers…
For regular drinking, it is never a bad idea to go into a supermarket and to take a box of Gulpener Biologisch (organic). Gulpener harvests all their ingredients close to the brewery. They have three variants, a regular Pilsner, a Weizen and an IPA. Recently I drank their organic Pilsner again after choosing mostly their IPA variant, and realised that it is close to defining Pilsner. Their IPA is also never disappointing, and one that stands above many of these cooler smaller fancy (read more expensive) IPA’s.
Then what other beers? Amsterdam itself has lots of smaller breweries, biggest of the smallest is Brouwerij ’t IJ. Try Columbus for a heavier one (9%; IJ is the name of the river through amsterdam, which is in pronounciation not different from Dutch ‘ei’, which translates to egg, hence all kinds of twists around egg, egg of columbus etc. [Troost](https://bro…
Recently a colleague was showing me a concept he was working on. He drafted a change in a fight against so-called 1+n-queries (actually for some reason unknown to me they're called n+1 queries, but my head isn't able to process the problem with just one more query after n queries…); in software development using ORMs like active record it is quite easy to make a single database request objects that when a presented within a view trigger other queries for every object because it has a relationship. Round trips to databases are generally bad as they take time.
For his change, he introduced a new class that we could seemingly reuse, with a just another (a bad code-smell) declaration of relations between objects and whether these should be preloaded when retrieving the primary object. This was in response to indeed a quite bad part of our code that entailed returning objects with counts of selected associations, but instead of counting these in the database, the current code was a…
Around 2000 I worked on Java Web apps using Eclipse, an open source IDE, which was also extendable with all kinds of tools. Since it was an IDE some made tools for drawing code with UML (connecting named boxes with attributes). But it was also the playground for tools less related to coding. It became a kind of OS running on an OS.
Less niche, was perhaps Netscape Communicator. It was a web browser, an email client, a webpage builder, a calendar … all in one. And also quite extendible again with plugins. The idea still lives on in the Mozilla Seamonkey-project.
A remnant of this is perhaps Microsoft Outlook. An e-mail client with integrated calendar app. An approach mimicked by Evolution on Linux.
I was reminded by all this [because Mozilla wants to focus on integrating AI in their flagship product Firefox](https://arstechnica.com/gadgets/2024/02/mozilla-lay…
So I wrote a few short articles on when to use FormObjects and Jobs and ServiceObjects. The question is of course "it depends", but the leading principle I have is keep it simple. That being said, for inspiration, some suggestion for different layers to manage the application complexity from Vladimir Dementyev's talk on Railsconf:
Dit artikel van murblog van Maarten Brouwers (murb) is in licentie gegeven volgens een Creative Commons Naamsvermelding 3.0 Nederland licentie .