about:benjie

Random learnings and other thoughts from an unashamed geek

Switching to Yarn Workspaces: An Example

| Comments

Wow, it’s been a fair while since I last blogged! Well: let’s get straight to it!

Yesterday I discovered that yarn (the alternative npm client from Facebook) had introduced a new feature called yarn workspaces which makes working with monorepos a lot easier. I’m working on a couple of projects recently that use the monorepo approach (one is a client project in which I introduced the monorepo approach to share code between React, React-Native and Chrome extension apps easily; the other is the Graphile OSS project I’m currently working on). We’ve had a few minor irritations working with lerna, the most notable of which is that when we want to install a new dependency we can’t just yarn install it - instead we have to add it to package.json and run lerna bootstrap again. At first this wasn’t so bad, but it quickly becomes a chore!

Upon reading the announcement it immediately sounded like yarn workspaces would solve this problem (and more!) so I decided to get on board!

So, without further ado, here’s how I switched graphile-build to yarn workspaces (still with lerna):

Long Live CoffeeScript and Long Live ES6

| Comments

Clearly ES6 is a huge improvement over ES5, and tools like 6to5 allow us to use these cool features now. I was reading Replace CoffeeScript with ES6 by Blake Williams and thought it was a great summary of how ES6 solves many of the same problems that CoffeeScript solves; however I’d like to comment on a few of Blake’s points and talk about why I’ll be sticking with CoffeeScript.

Classes

Classes in ES6 (like many of the syntax changes in ES6) are very similar to the CoffeeScript equivalent. To support browsers that are not fully ES5 compliant (e.g. IE8-), however, we still can’t really use getters/setters, so ignoring these the comparison is:

Quantum JavaScript?

| Comments

TL;DR: In Chrome or Safari’s JavaScript console (or in jsc, but not node), run the following:

1
2
3
4
> {} + {}
NaN
> var a = {} + {}; a
'[object Object][object Object]'

a) Why is the first result wrong?
b) Why does storing it to a variable (observing it) change it?

(The answers are below.)


My friend Anton pointed out to me this short ‘WAT’ talk by Gary Bernhardt from 2012. It did something that confused me somewhat. Here’s what Gary’s example was:

1
2
3
4
5
6
7
8
9
$ jsc
> [] + [] // 1

> [] + {} // 2
[object Object]
> {} + [] // 3
0
> {} + {} // 4
NaN

Now 1 and 2 are fine, but 3 and 4 immediately went against what I was expecting - it truly was a ‘wat’ moment. I noticed was he was running this in JavaScriptCore, let’s see what Node.js makes of it:

1
2
3
4
5
6
7
8
9
$ node
> [] + [] // 1
''
> [] + {} // 2
'[object Object]'
> {} + [] // 3
'[object Object]'
> {} + {} // 4
'[object Object][object Object]'

Node.js seems to be doing exactly what I’d expect - using the + as string concatenation (since the leading argument is not numeric). So it’s calling .toString() on everything to produce the results you see above (an Array’s toString is effectively return this.join(","), and since it’s empty it just returns the empty string).

So what’s going on?! Let’s try V8 (the engine behind Node.js) in the browser (Chrome):

My Favourite Git Commands IV: Cleaning Up

| Comments

This is part 4 in my Favourite Git Commands series.

Cleaning up

Whether you want to do a quick bugfix in a different branch or just get rid of all your debugging, keeping your working directory clean is a good idea. Another way to do this is to use git reset --patch from part 1.

git stash

The stash is where you can store local modifications which you can then restore later.

Quickfix in other branch

If you need to hop to another branch but you’re in the middle of something then this type of thing works great:

My Favourite Git Commands III: Editing History

| Comments

This is part 3 in my Favourite Git Commands series.

Editing History

You should never change a commit that has been shared with someone else - it makes everything very confusing for your collaborators. This is one of the many reasons you should always be aware exactly what you’re committing. However…

It’s often useful to edit, reorder, split or merge your local (unpushed) commits - for example you might want to fix a bug you introduced 2 commits ago that you don’t want anyone to ever know about. EVER. This ability to easily edit history, fix mistakes in commits (for example if you accidentally added a password) and generally control your revision history is one of the things that makes git so powerful in my opinion.

git commit --amend

My Favourite Git Commands II: Viewing Changes/History

| Comments

This is part 2 in my Favourite Git Commands series.

Viewing Changes/History

A distributed version control system is very useful at helping you to track down bugs, revert to previously working versions, and especially for collaborating with other (remote) users. But you can lose many of these benefits if you don’t keep your revision history tidy.

I find the best way to do this is to keep each commit small and focussed on just one feature. Unrelated changes and fixes should go in their own commits, even if this means that you’re committing just one line: “fix typo in random number generator.”

My Favourite Git Commands I: Patch

| Comments

This is part 1 in my Favourite Git Commands series.

Last year I wrote a post about how I intended to switch over to and master the tools I’d always meant to but somehow never got around to. Among these was git.

I’ve now been using git exclusively for the last year (even when interfacing with SVN projects I do so using the awesome git-svn bridge) and I love it. It took me a while to form a decent workflow and break the old SVN habits, so over the next few days I thought I’d share with you some of my favourite git commands.

I’m going to assume that you’ve used git at least once or twice, and know what I mean by repo (where the git history is stored, i.e. the .git folder), HEAD (the top commit in the current branch), staging area (where the files for the next commit are stored, also known as the index or cache), and the working copy (the files that you’re modifying).

The --patch option

My friend Jasper helped a lot when I first started getting into git, and noted one of his favourite commands was git add -i - an interactive way of adding files to your staging area before commits. I used this a lot, but found that mostly I was using the patch function, and going through all the menus was unnecessarily slowing me down. Enter:

LightwaveRF RF Protocol

| Comments

Following on from yesterday’s success, I’ve done a big data capture of various commands and have figured out (mostly) the protocol.

As you saw yesterday, each command comprises 10 bytes. But actually, each of these only ever take one of 16 values, thus they really represent nibbles. The values of these nibbles are:

Lightwave RF nibble values
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 0 : 1111 0110
 1 : 1110 1110
 2 : 1110 1101
 3 : 1110 1011
 4 : 1101 1110
 5 : 1101 1101
 6 : 1101 1011
 7 : 1011 1110
 8 : 1011 1101
 9 : 1011 1011
10 : 1011 0111
11 : 0111 1110
12 : 0111 1101
13 : 0111 1011
14 : 0111 0111
15 : 0110 1111

Then the payload is made out of 10 of these nibbles.

Level (2 nibbles)