Back

The Practical Dev

A showcase of my new personal website

2018-01-12 21:14:31

WordPress Theme Development has come to my mind a ton of times, but never really had the time to get into it, until a few days ago. I decided to take my chance and build myself a personal website (because apparently everyone has one 😁). I fiddled around, figuring out what would the design be like, so I thought nothing represents me better than the tool I'm using, which is Visual Studio Code. So I spent my last weekend on making the WordPress theme. I downloaded this boilerplate and started to develop the site and learn about WordPress on the fly. So here's my site, check it out and I'm hoping you can give me some feedback! Thanks!

Read more

Testing legacy code, part 1: How to start

2018-01-12 20:08:46

I am starting this miniseries which is a continuation of my previous article on why I think legacy codebase should be tested. I will be more general in this part, but later I will be mostly writing about practical tips when working with Java codebase.

The intentions are clear, you should be able to benefit from this, if these points sound familiar:

  • you are maintaining a large codebase
  • you are in a process of refactoring old components (rewriting logic, upgrade)
  • you have no access to code history (original developers not present in the company, VCS history is unusable or repository was migrated, etc.)
  • you have no documentation, or it is outdated

How to start?

Static code analysis

In a situation like this you need to have systematic approach. First of all I recommend installing any of the tools for static code analysis. I cannot really tell why, but most legacy projects I've helped maintain/improve suffered from huge technical debt. In other words, code quality was some abstract term and static analysis was completely missing. I have found useful installing dedicated instance of SonarQube, that would be accessible to your team. Setting up quality gates should be individual, but I strongly recommend leaving at least standard configuration enabled.

Why is this important?

This analysis should give you an insight in what is actually wrong with the code and where potential issues may occur. You can then create test scenarios targeting these issues. For instance potential NullPointerException or issues with incorrectly closed streams. At this point, you should note them as some red flags which will point you to the part of system, that should be handled with higher priority.

SonarQube can give you a pretty thorough report on coverage, so if your goal is to actually find good testing candidates this is the place to start. It is also super easy to setup and benefits are clearly visible also for non-tech people (charts and such).

Individual code analysis

You will also need to invest some effort in individual analysis. These are my usual observations about legacy code:

  • code is not unit testable (large methods - no units, classes take too many responsibilities, dependency injection is missing, complex class hierarchy, etc.)
  • business logic is complicated and requires a lot of test data preparation
  • external libraries or 3rd party applications are required to perform certain operations (external API, database, etc.)

These all are potential deal-breakers when you try to use simplistic approach. All of the problems above can be mitigated at some cost, but at this stage, you should focus on what information you have about system you want to test.

Follow the thread

Whether it is a web application or an integration project, you should prepare some scenarios, that would copy real-life usage. E.g. if the implementation is not clear, it should at least be clear what the system does overall.

For example, if the application exposes public APIs, start with writing API tests. If it is a backend "data-processing" system, try to come up with possible test/expected data, and so on. Usually you should look for something I like to call the least obscure blackbox. It is a component with known functionality, but unknown implementation.

Why is it important?

You won't achieve much success without this kind of analysis. Testing something mechanically may not discover problems in implementation, since you can end up with tests that test the wrong implementation. If it is clear, you should always go with scenarios.

Putting it all together

Depending on your results, you should be able to come up with these isolated cases:

  • functionality to be tested (formulated as task)
  • current test coverage (generated report)
  • possible errors in implementation (summary from static and individual code analysis), that will help prioritize case
  • individual remarks, depending on available knowledge (importance, frequency of usage, external dependencies, etc.)

With these cases prepared, you can start implementing the tests. In the next articles, I will target specific problems and possible solutions.

Read more

Weekly Web Roundup - 02

2018-01-12 17:53:17

Week 2

Another week, another roundup! I’m starting to get really excited for all the things that 2018 will bring us. This week I've got some news, articles on all the main subjects and spiced things up with a bit of inspiration as well. Let’s get to it.

News

npm operational incident, 6 Jan 2018

Technically that was last week but I found it worth a mention. Around a hundred packages falsely got flagged as malicious and as a result were unavailable (github issue). The problem was resolved pretty quickly but it shows how big our dependency on a functioning npm is. It kind of feels like we’re throwing all our eggs.js in one basket. More about this in the Security section.

Chrome is turning into the new Internet Explorer 6 on theverge.com

I wouldn’t put it in those words, but since I’ve been using Firefox as my main browser I definitely notice that there’s a certain amount of ‘Chrome’ only sites, including some Google services, and that sucks. Of course, Chrome is still a great browser and Chris Coyer reminds us of the true horrors of IE6 in his ‘[careful now[((https://css-tricks.com/careful-now/)
)’ story on CSS-Tricks.com.
That being said, I must admit that my Firefox seems to perform pretty horrible with animations. Maybe I should give Vivaldi a try?

A letter about Google AMP

Talking about Google controversy, how about that AMP huh? There's a letter you can sign that voices an opinion against AMP. I'm not sure if it'll do much good but at least it's a sign.

Security

I’m harvesting credit card numbers and passwords from your site. Here’s how. by David Gilbertson on hackernoon.com

Do you know what your npm dependencies depend on? Do you know what your npm dependencies of dependencies depend on? David Gilbertson sketches a horror scenario in which he infects several NPM packages with malware and spreads it around like wildfire.

Should we DEMAND the latest browser version? by Alex Ewerlöf

YES! Or you know, it would be pretty damn convenient to only build for the latest browser versions because security. Any arguments against this?

CSS / SVG / HTML

Articles

What’s New in HTML 5.2? on bitsofco.de

HTML 5.2 became a recommendation and brings us new goodies. style tags are finally allowed inside the body, a native dialog element and more. Read it all in this excellent article.

Books

Using SVG with CSS3 and HTML5: Vector Graphics for Web Design by Amelia Bellamy-Royds

If you want to get in-depth with SVG, CSS3 and HTML5 I can't recommend you anything better than this book by Amelia Bellamy-Royds. I haven't even read it yet but I feel confident in giving my full recommendation.

Tutorials

Learn CSS Grid for free

A free CSS grid tutorial. Seriously, why wouldn't you? By Per Harald Borgen

Ethics

Blockchain & Cryptocurrency

Telegram plans multi-billion dollar ICO for chat cryptocurrency on techcrunch.com

"THIS IS HUGE!" according to some. To be honest, I barely know what it means. Remind me of this post when you got rich of Telegram-dollaz.

Inspiration

The innovative Data Visualization & data art of Nadieh Bremer

Nadieh Bremer is a freelance data visualization artist who makes amazing work, like this gorgeous The Guardian article. I love this type of work as it brings so much more information and value to an article. I can't wait to see what Nadieh will be producing in 2018.

Analytica Projects by Veintidosgrados

It's quite a trade-off, a long loading time for not a lot of information. Yet the story telling element is nice and the scrolling is oh so smooth (and only slightly induces motion sickness)

Abel Odor by buildinamsterdam

Argh, sound! But other than that this webshop is pretty damn cool. The site is WooCommerce based, which makes it even more impressive as WooCommerce is a mean beast to tame. The people at buildinamsterdam know how to give a webhop a dynamic and fresh feel like no other though.

Case Study: lynnandtonic.com 2017 refresh

If you haven't seen Lynn Fisher's beautiful portfolio page with a gazillion breakpoints yet, make sure to have a look right now. In this medium post she explains what her motivation behind this intricate design was.

Accessibility

Javascript

JavaScript Tutorials

Testing

But really, what is a JavaScript test? - By Kent C. Dodds

Testing isn't that scary as you'd might think. Kent created this awesome 101 which will get you started in the world of JS testing!

Tools

Tools

React

React Router course by Tyler McGinnis

Tyler McGinnis released a React Router v4 course and because of that he temporarily offers 25% discount on his courses.

GraphQL

A Practical GraphQL Getting Started Guide with Node.js - by John Kariuki on scotch.io

My introduction to GraphQL was with GatsbyJS and I’ve been a fan right from the start. You’re going to hear a lot about GraphQL this year, and this article by John Kariuki is a very nice and practical introduction to the goodness that GraphQL brings.

GraphQL, here is what you need to know - Syntax.fm podcast

Syntax.fm is the podcast (that brings you tasty web development treats… I’m not sure why but that quote gives me an icky feeling) from Wes Bos and Scott Tolinski, and apart from the tagline it’s awesome. The last episode is about GraphQL and it’s very informative and probably will get you to try something out right away.

Optimization

Hosting

Productivity

Podcasts

Pursuit Podcast

How come I didn’t know about Pursuit Podcasts before? They’re so good! They’ve got some great guests, the last two being Rachel Andrew and Sara Soueidan. Rachel talks about time management, while Sara has a great talk about contracting work.

Random

What happens when you type google.com into your browser's address box and press enter?

This is a way too in-depth explanation, and it’s pretty good.

Shower thoughts

Be nice!

So often I come across great resources and work I appreciate, but I kinda forget to show that appreciation to the makers. Lately I’ve been trying to actively search the creators of content just to tell them I really enjoyed what they made.

Are coding tests a good way to weed out candidates?

I’m only asking because I’m about to do my first one. Besides pub-quizzes I haven’t done much tests lately.

What have I been up to?

Quick! Tell me everything you know about Codility tests.
Also, I made a start on Kent C. Dodds Advanced React Component patterns course on egghead.io and it’s been pretty great so far. I will keep you tuned.

So what have you been up to?

Enjoy the weekend, don't work too much!

Read more

CSS Modules in 30 Seconds

2018-01-12 17:50:24

CSS Modules allows us to write CSS rules that are restricted to a certain part of the UI. It is not an official specification or browser implementation, but rather a process enabled by a build tool like Webpack. In contrast to a regular CSS selector, which can match any element, a CSS Modules selector can only match elements in a specific part of the UI (e.g. in a specific React Component). Build tools accomplish this by transforming the selectors we write into new, globally unique selectors and then applying the new selector to the associated UI element.

Read more

Ambassador and Istio: Edge proxy and service mesh

2018-01-12 17:15:41

Ambassador is a Kubernetes-native API Gateway for microservices. Ambassador is deployed at the edge of your network, and routes incoming traffic to your internal services (aka "north-south" traffic). Istio is a service mesh for microservices, and designed to add L7 observability, routing, and resilience to service-to-service traffic (aka "east-west" traffic). Both Istio and Ambassador are built using Envoy.

Ambassador and Istio can be deployed together on Kubernetes. In this configuration, incoming traffic from outside the cluster is first routed through Ambassador, which then routes the traffic to Istio. Ambassador handles authentication, edge routing, TLS termination, and other traditional edge functions.

This allows the operator to have the best of both worlds: a high performance, modern edge service (Ambassador) combined with a state-of-the-art service mesh (Istio). Istio's basic ingress controller, the ingress controller is very limited, and has no support for authentication or many of the other features of Ambassador.

Getting Ambassador working with Istio

Getting Ambassador working with Istio is straightforward. In this example, we'll use the bookinfo sample application from Istio.

  1. Install Istio on Kubernetes, following the default instructions.
  2. Next, install the Bookinfo sample application, following the instructions.
  3. Verify that the sample application is working as expected.

By default, the Bookinfo application uses the Istio ingress. To use Ambassador, we need to:

  1. Install Ambassador. See the quickstart guide.
  2. Update the bookinfo.yaml manifest to include the necessary Ambassador annotations. See below.
  1. Optionally, delete the Ingress controller from the bookinfo.yaml manifest by typing kubectl delete ingress gateway.

  2. Test Ambassador by going to $AMBASSADOR_IP/productpage/. You can get the actual IP address for Ambassador by typing kubectl get services ambassador.

Automatic sidecar injection

Newer versions of Istio support Kubernetes initializers to automatically inject the Istio sidecar. With Ambassador, you don't need to inject the Istio sidecar -- Ambassador's Envoy instance will automatically route to the appropriate service(s). If you're using automatic sidecar injection, you'll need to configure Istio to not inject the sidecar automatically for Ambassador pods. There are several approaches to doing this that are explained in the documentation.

Read more

What is Time Complexity?

2018-01-12 16:20:19

An introduction to time complexity: how to count the steps in a program. A look at worst case, average case, and mention of best case. The relevance to profiling, efficiency, collections and encryption.

Watch my streams live on Twitch - Mortoray

Read more

Let's talk about emojis

2018-01-12 11:44:44

Emojis are everywhere. From Twitter to Facebook Chat, they've grown to become Oxford's 2015 Word of the Year and even featured in a horrendous movie. But what about outside SMS and instant messaging? What about using emojis inside code comments or even git commit messages? Let's find out how we can make the best use of these funny little pictures.

Contrary to what people may think, emojis have been around for quite some time. The first emoji dates back to 1999, and was created by Shigetaka Kurita, a Japanese telecommunication planner for NTT Docomo. At first used solely in Japan, it took those little pictures ten years for some of them to be added to the Unicode character space. Thus, in October 2010 the Unicode Standard 6.0 got released, and with it 722 emojis. They do not live in their own dedicated blocks though and are spread around the Unicode tables. It took years for multiple engineers working at Google and Apple to convince the Unicode Technical Committee to add them. Now emojis are a part of everybody's life.

There are even some quirks and fun little facts about these tiny pictures. For example: emojis can vary from one platform to another. Because of that, the calendar emoji is represented always showing July 17 on Apple products (that date representing the announcement of iCal back in 2002). This led people to "wrongfully" declare July 17 World Emoji Day.

Emojis are also represented differently across platforms, and can be interpreted slighly differently. Take for instance the astonished face emoji. The first one is Apple's interpretation, the second one is Samsung's.

emoji1

Apple's take on this feeling feels a bit more tamed than Samsung's, don't you think?

Other times, it can be the contrary. In this example, Samsung's interpretation of the pouting face feels less "angry" than Twitter's.

emoji2

But enough with the history, let's get down to coding.

Emojis in git commit messages

Github has popularized emoji support inside their ecosystem in a blog post from 2012 thanks to their now famous ":" shortcut. So now, say you want to use the fox face emoji 🦊 somewhere in Github (a commit message, an issue or a gist), you can simply use :fox_face: instead and it will automatically be interpreted by Github.

Using shortcuts is an elegant solution to circumvent emojis not being interpreted. You don't take the risk of breaking something and even if they're not (or badly) rendered, the messages are still readable.

Emojis can also add a lot of clarity to commit messages. Compare these two sequences:

- Fix editing user not being saved to the database
- Cleanup code
- Add the ability to edit a user
- Fix bad function callback on API request
- 🐛 Fix editing user not being saved to the database
- 📝 Cleanup code
- ✨ Add the ability to edit a user
- 🐛 Fix bad function callback on API request

You can immediately see where bugs were fixed and where new features were added.

On a platform that doesn't support emojis, this would be read as:

- :bug: Fix editing user not being saved to the database
- :memo: Cleanup code
- :sparkles: Add the ability to edit a user
- :bug: Fix bad function callback on API request

Definitely not as fun, but still perfectly readable.

The tech industry as a whole appropriated these shortcuts and went far beyond simple emojis. Sure it's nice to use 🐛 to talk about fixing a bug, but try using :trollface: in Slack or Redmine. Boom, you're the new cool kid on the block. Don't use it too often though, you don't want to be that guy.

My advice: Don't hesitate to use emojis in git commits, but do prefer short-codes. I would also suggest not to go overboard with it and stick to a list of a few ones to denote the major actions (bugfix, new feature, styling, code cleanup, etc..).

If you're not sure were to start or want to suggest a guideline for your team, I highly recommend Carlos Cuesta's Gitmoji. It even comes with a nifty CLI (simply called gitmoji-cli) which will help you write your commit messages through an interactive interface. Gitmoji is even used in Atom's contribution guideline.

Emojis in/as code

Technically, you could use emojis in computer code, but you should be very careful when doing so. Emojis are interpreted as strings in Javascript, but their length can vary.

"🐼".length         // returns 2
"🇨🇦".length         // returns 4

Don't forget emojis can be connected (kind of the same way Fira Code gets you those sexy sexy ligatures). That's how you can now get skin color modifiers (called EMOJI MODIFIER FITZPATRICK TYPE-1, -2, -3, -4, -5, and -6. I'm not kidding). Or even better, if you combine the following emojis: 👨, 👩, and 👧, you get a whole family 👨‍👩‍👧! Let's run that through Javascript.

"👨‍👩‍👧".length         // returns 5

Why 5? Because not only do you get the length of each emoji that symbol is made of, but it also uses two ZWJ (Zero Width Joiner) characters as "glue". You can even see it in action: copy/paste that emoji inside VS Code for instance, and it'll take you five "arrow key" strokes to go through it.

My advice: Do not to use emoji in code logic. Plain and simple. But you can still use them in your views. Web browsers have amazing emoji display capabilities, and know how to fallback to a font that will display your "thump up" icon. But watch out and be careful when using an emoji short-code interpreter in those views, especially if you happen to display code blocks on your website. It could trick you, interpreting h:m:s as hⓂ️️s, thus making the code block useless.

Emojis in code comments

So what about code comments? Emojis everywhere! As far as I know, you are not susceptible to break anything because of emojis in comments. Modern code editors (Atom, VS Code, Sublime, Intellij...) have amazing emoji support. They even can be pretty useful to make something stand out.

/**
 * WARNING: Do NOT change this file.
 */

Compared with:

/*
 * 🛑 WARNING: Do NOT change this file.
 */

Final thoughts

Emojis are a double edged sword. They allow us to express complicated feelings in a quick and fun way. They are the extension of the emoticons we used profusely back in the IRC glory days. They can be used as decorators, adding feeling to an otherwise plain sentence. They also can be used as markers to make something stand out, and even as a complete communication tool when used on their own.

However, since they're not designed and interpreted uniformally across platforms, they can be the source of misunderstandings. Communication relies on the stability of its mean of propagation. If a symbol is changed between the sender and the receiver, the message is not the same. As characters, they also need to be put in context. That's why some of them had to be changed. For instance the :gun: emoji 🔫 which used to be represented by a real gun, is now a water pistol.

When it comes to code though, I'm all in favor of using emojis. Not in the code itself, as I've stated, but rather in comments and commit messages. They embelish the message they're attached to, for they are generally mainly used as pointers. And with the help of short-codes, you can use them without the fear of breaking something.

If you want to know more about emojis, you should check out Monica Dinculescu's work, and especially her talks.

I also recommend Angela Guzman's post on the making of Apple's emoji. Angela writes how she and her mentor Raymond designed over 500 emojis during her internship back in 2008. This changed her life, and her work is now in the hands of millions of people.

So go ahead and emoji away, you'll improve readability and break away from the monotony of a dull screen filled with code. 😄

Read more

My Mac Setup

2018-01-12 11:00:00

Maybe I should start a series called “Not just a Gist”, as I’m slowly converting gists of mine to blog posts. The last one I converted was all about My Visual Studio Code Setup.

I participated in this week’s #devdiscuss about tooling, and I posted a few links to gists that are my setup on my Mac.

Nick Taylor
@nickytonline
Twitter
02:10 AM - 10 Jan 2018
Twitter reply actionTwitter retweet action0Twitter like action2

Tools you absolutely need on your Mac

  • The Homebrew duo. These are a must have to simplify installing most things on your Mac. As soon as these are installed, you may proceed.
  • Homebrew - run /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" from the command line to install it.
  • Homebrew Cask - run brew tap caskroom/cask from the command line to install it.
  • Spectacle, the best application I’ve found for managing windows on MacOS. This is especially useful for anyone coming from Windows who are used to this out of the box functionality. Run brew cask install spectacle from the command line to install it.
  • Alfred (buy the Alfred Powerpack to get the full use of Alfred). Run brew cask install alfred from the command line to install it.

Alfred Setup

Alfred is so awesome, it deserves it’s own section in this post. It’s basically Spotlight on steroids and a bag of chips. It’s more than an application launcher. It allows you to create workflows for repetitive tasks you do everyday and there is also a huge array of existing workflows for it available. I even decided to make some of my own, nickytonline/alfred-workflows: Hopefully useful workflows for Alfred.

Nick Taylor
@nickytonline
Twitter
@ThePracticalDev @code @alfredapp Also, this Alfred workflow is awesome for my workflow with GitHub, github.com/gharlan/alfred… #devdiscuss #git
02:21 AM - 10 Jan 2018
Twitter reply actionTwitter retweet action0Twitter like action1

I never used Alfred until this past summer. Why did I not use it sooner?!

(╯°□°)╯︵ ┻━┻

The Syntax FM podcast has a great episode on tooling, including Alfred, Our favourite Productivity Hacks 🔥 — Syntax Podcast 011. You should check it out.

At the time of this writing, here’s all the workflows that I currently have installed:

If you use Alfred and have some workflows that are not listed here, please mention them in the comments. I’m always looking for new ones to improve my whole dev workflow.

Tools for Web Development

  • VS Code, here’s my setup. Run brew cask install visual-studio-code from the command line to install it.
  • n, run brew install n from the command line to install it.
  • now.sh, great for hosting but also great for knocking out some POCs and deploying it. Run brew cask install now from the command line to install it.
  • Docker, containerize all the things! Run brew cask install docker from the command line to install it.
  • FiraCode font for my shell and my favourite editor.

Shell/Terminal Setup

  • iTerm2 - run brew cask install iterm2 from the command line to install it.
  • Fish shell - run brew cask install fish from the command line to install it.
  • Fisherman, run curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher from the command line to install it.
  • edc/bass (to support bash utilities) - Assumes Fisherman is installed. Run fisher edc/bass from the command line to install it.
  • I use the git CLI with git aliases. Here’s my list of git aliases.

Useful Utilities

  • Unarchiver - run brew cask install the-unarchiver from the command line to install it.
  • Amphetamine, sometimes you just want your laptop to stay awake… 💊
  • VLC - run brew cask install vlc from the command line to install it.
  • f.lux, so you can be nice to your 👀 in the evening. Run brew cask install flux from the command line to install it.
  • Dropbox, I use it to sync my Alfred settings, fish, fisherman etc. via symlinks.Run brew cask install dropbox from the command line to install it.
  • dark-mode - run brew install dark-mode from the command line to install it.
  • vanilla for OS X menu bar. Hide the clutter. Run brew cask install vanilla from the command line to install it.
  • Slack
  • Trello, I’m using this less and less though since I discovered Bear. I’ve fallen more in a todo list mode with Bear.
  • Bear, this is definitely my favourite new app. It’s the first note taking app that I’m consistently using. I think it’s all due to markdown support and simplicity.
  • LiceCap, for animated GIF screen captures. I find this tool very easy to use and the animated screen captures are pretty decent. Run brew cask install licecap from the command line to install it.

Tweaking MacOS

  • Prevent Mission control from rearranging Spaces. This drives me nuts, so I remove the setting. I arrange my spaces because I want them to stay like that.
  • If you’re on a Mac with a Touchbar, map the function keys to always be used when in browsers, your editors or any other tools you use for dev.

That’s pretty much the round up of what I have on my machine at the moment. I should probably get around to writing a script that installs all this, but for the time being, other priorities.

I’m always looking for new tools to make me more efficient, so feel free to chime in in the comments below.

Read more

Inheritance in Swift

2018-01-12 09:24:29

A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. A class that does not inherit from another class is known as a base class.

The above code snippet shows how the someSubclass inherited from the someClass class. Classes in Swift can call and access methods and properties belonging to their superclass and can provide their own overriding versions of those methods and properties to refine or modify their behavior. Classes can also add property observers to inherited properties in order to be notified when the value of a property changes.

Accessing Superclass Properties and Methods

Assuming we have a base class named Person and a Youtuber class that inherit from the Person class

The first thing I want us to notice is the class Youtuber: Person{}. We simply said the Youtuber be a type of Person which make it inherit all the properties and method of the Person class.

Secondly, when we initialize the Subclass, we use the super.init() method to pass the parameters needed by the superclass constructor since a Youtuber is actually still a Person.

We can access the celebrateBirthday() method of the Person class from the Youtuber subclass like below

Overriding Methods

At times, the subclass might wish to override a method contained in a superclass. We will make use of the override keyword within the subclass like below:

I initialized the Person class as well as the Youtuber class, the celebrateBirthday method in the Person class will return a different value to the Youtuber class because of the override function that print a different content in the Youtuber class.

Overriding Properties

we have seen how to override methods in swift, but there are cases where we actually need to override properties.

Immediately after the super.init() in the inside init method, we set the country variable. Note that, we can only do this after we have initialize the superclass.

Preventing Override

We can prevent a method or property from been overridden by a subclass by using the keyword final func or final var.

There is more to inheritance like observers. Didn’t cover that here because am not pretty sure how to use it now. Will update this article when I fully understand the concept. Lemme go read up enum and optionals. Yes, will write about it when done.

_I am happy to share this article with you.

Read more