Matthew Lindfield Seager

Standing room only at Rorosyd this evening!

Great talk by Donna Zhou on how to give a good talk! šŸ™‚

Today I needed to GET a list, pluck the IDs and then do a DELETE request per ID.

I did the first part with Postman but quickly rejected it for the looping/deleting part.

I probably should have used Ruby but next I reached for Shortcuts, a versatile Swiss Army knife on an iPad!

I love learning new Git tips and tricks, especially when they explain the why as well as the what!

Changing the Rules of the Gamification

From walking on the spot before bed to reach 10,000 steps in Pedometer++ or going for late night jogs to close my rings I’ve discovered I’m a sucker for gamification… completion metrics especially, but also streaks (and badges to a lesser extent).

While that’s probably not a bad thing if it means I go for an extra walk, the same instincts sometimes cause me to stay up way too late levelling up in free to play games or to neglect useful or more important things in my life to complete a series on Netflix.

Conversely, I haven’t been great at consistency or persistence in my life. I’ve never managed to learn an instrument or a second language because they’re not really things I can accomplish in 6 weeks before I lose interest.

Knowing these two things, I have tried to craft my environment to limit how much I get tricked into doing things I don’t really want to do while simultaneously trying to trick future me into doing things that I want to do in principle but don’t want to do in the moment.

Some of the things I do to protect myself include:

  • pay for games up front, as these games tend not to be ad-supported and usually don’t have exploitative game mechanics
  • delete a game outright if I find it’s taking over my life (because I certainly won’t just decide to play it less)
  • increase the friction to play games by only installing them on my iPad (which I don’t always have with me) or using Screen Time to help make myself aware of how much time I’m spending on them
  • don’t allow push notifications which might tempt me back in to the game or app (in fact, all my notification settings are quite strict, especially on my watch which I wear 23/7)
  • only subscribe to Netflix/Stan/whatever one month a year (and then only during holidays) so it’s not a constant temptation

On the flip side, late last year I started to deliberately try and build positive habits. Some of the approaches I am using include:

  • using the Streaks app to track my progress and encourage consistency (“streaks”)
  • starting with small, easy to accomplish tasks which I have been adding to as they become routine (my first habit was brushing my teeth every day)
  • choosing streak rules that require me to complete the task every day, or close to it, to help normalise the behaviour (e.g. posting to this blog). While I’d rather write an essay every week, I find once a week habits are too easy to break… miss one and there’s a two week gap, miss two and it’s been almost a month. Which flows nicely into my next point…
  • making the bar to complete a task very low so I at least get started. I’m much more likely to get started if the task is “pray for 1 minute” rather than “have a 15 minute quiet time”. Once I start I often do more, but I don’t have to, so the task is achievable, even if I’m exhausted or feeling down. Other examples include “post something to M.b” (280 characters is a lot more manageable than 500 words), “read 1 paragraph” or “do 1 sit up”
  • giving myself permission to not be perfect by allowing a rest day or two in a week to maintain a given streak (e.g. 5 days a week of non-work software development learning/practise)

I’ve still got a long way to go when it comes to consistency and persistence but I think I’m making progress!

I enjoyed watching my son doing some code.org challenges today. And I only offered him unsolicited advice once! šŸ™‚

It reminded me a bit of the Learn to Code courses in Swift Playgrounds that he and my daughter started previously. Iā€™m interested to see where it all leads.

Pretty disappointed that even with a strong surplus the 2019 Australian budget leaves foreign aid at 0.21%, the lowest level itā€™s ever been (video, commentary).

At a time when unrest, global hunger and slavery are all increasing, we can and should be doing more with our wealth.

I love this Rails PR (and the original code it removes).

Some crazy optimisations/shenanigans were introduced but:

  • it was well documented
  • it solved an actual need (a hotspot in frequently used framework code)
  • it was removed once no longer needed

Open source done well!

šŸ“š Iā€™ve spent a decent chunk of today reading (listening to) Heads You Win by Jeffrey Archer.

Iā€™m about 2/3 through and can highly recommend it! (Just donā€™t click on the above link if you donā€™t want a mild spoiler shoved in your face)

The Amazing State of Technology in 2019

Book a private car 24x7 with no notice. Track it in real time. Shows up within a minute of scheduled time.

Public buses and trains run night and day. You can track them in real time. They show up within a minute or two of the scheduled time (or a replacement comes soon after).

Book an ISP technician for a suitable day (weeks in advance and only during work hours). ISP actually schedules it several days later (without asking, even though you arenā€™t available). You organise someone else to be on site for a 5 hour(!!!) window (canā€™t track technician in real time) but technician never shows (and you donā€™t even get an explanation until the next day). ISP reschedules for ā€œearliest possible appointmentā€… a week and a half later (almost 4 weeks after original request, not on a suitable day and they didnā€™t even provide a window, this time someone needs to be on standby all day).

To make it worse, this is for a business (i.e. costs extra), stock standard DSL connection (no bleeding edge technologies to figure out), from the second biggest ISP in the country!

My wife and I have been trying to not let busyness be an idol.

I like the premise behind ā€œNo points for busyā€ but I think we can do better than ā€œpoints for efficiency and productivityā€…

Points for being present? For actually listening? For putting othersā€™ needs first?

Iā€™m looking forward to the inaugural RunWest 12km fun run tomorrow. My goal is 54 minutes or less.

After that itā€™s time for some longer runs with only 61 days until my second marathon.

Passion is a consequence of effort, not just a cause
ā€” Adam Grant on the WorkLife podcast (overcast link)

In Advanced ActiveRecord Querying I learned you can nest joins.

I knew about joins(:suburb) but didn’t realise you can join further, e.g. joins(suburb: :state).

You could even joins(suburb: { state: { country: { planet: { solar_system: :galaxy }}}})!

N.B. Could ā‰  Should

In Praise of Apple, Iteration and Ecosystems

I know itā€™s trendy to pick on Apple but Iā€™m really impressed by how smooth the Apple ecosystem is these days:

  • My phone unlocks my watch for the day which in turn unlocks my laptop every time I wake it up
  • Copy on one device, paste on another just works
  • Send SMS (not just iMessage) from phone, (wifi) iPad or laptop
  • Shared passwords between all my devices without even thinking about it
  • Auto-entry of one time banking confirmation codes (now with the amount auto detected too!)
  • Approving screen time requests on my watch for kids iPads
  • Switch Beats headphones from one device to another effortlessly
  • Continue reading a web page from one device on another (plus iCloud tabs for stuff thatā€™s open on the other device)
  • Maps directions in sync on phone, watch and CarPlay screen
  • Universal keyboard replacements work everywhere. Some are useful, like @@s for my email address… some are frivolous, such as zshrug for ĀÆ\_(惄)_/ĀÆ
  • Airdrop, between my devices and to other peoplesā€™
  • AirPlay from Mac, iPad or iPhone

I think thereā€™s probably others but more and more I just do them without thinking (whereas I used to wait with bated breath to see if it would be successful). It seems to me like Apple has just been quietly iterating and improving each of these features to the point where they now feel rock solid and indispensable!

Mind. Blown.

Double-click a curly, square or round brace in the Mac terminal and it automatically selects the braces and everything inside them!

Great for quickly grokking complex objects in a Ruby console or large slabs of JSON!

Most problems donā€™t require more data. – Seth Godin - Data Into Information

Iā€™m sure big data has uses but Iā€™m yet to work in an org that has truly solved little data. Why make it any harder?

Data + Structure = Info
Info + Insight = Knowledge
Knowledge + Judgement = Wisdom

ActiveRecord - solving for value is NULL or is not in list

Today I encountered an issue where 2 + 2 was only equalling 3 when fetching data using ActiveRecord in Rails.

def permanent_staff
  People.staff_like.where(
    contract_type: Settings.permanent_staff_contract_types
  )
end

def non_permanent_staff
  People.staff_like.where.not(
    contract_type: Settings.permanent_staff_contract_types
  )
end

People.staff_like.count == permanent_staff.count + non_permanent_staff.count
=> false # (huh!?)

After a little bit of digging I realised some People were being excluded because they didn’t have a contract type:

People.staff_like.count == permanent_staff.count + non_permanent_staff.count +
  People.staff_like.where(contract_type: nil).count
=> true

I assumed those with a NULL contract type would be included in non_permanent_staff but it turns out that’s not how databases work (at least not how PostrgreSQL or Sequel Server work, but I’m pretty sure this is “standard” behaviour). As soon as the query optimiser sees contract_type NOT IN (... it filters out any results that don’t have a contract_type.

My solution doesn’t feel like idiomatic Ruby or Rails but I solved it with the following method:

def non_permanent_staff
  People.staff_like.where.not(
    contract_type: Settings.permanent_staff_contract_types
  ).or(People.staff_like.where(contract_type: nil))
end

The generated SQL is a bit ugly (the staff_like scope conditions gets included twice) but I’m sure the database can optimise that… better the DB deal with the data collection than Ruby.

If this method proves confusing to future-me I may just put a NOT NULL constraint on contract_type in the database and be done with it. It’s a string we’re importing from a legacy system so the default value would just be “.

In Praise of RailsCasts

When I was looking for information on Rails Metal/ActionController::Metal the other day I was struck once again by what a great resource RailsCasts is.

The Rails Metal episode is still up even though it’s no longer applicable, providing a useful historical perspective. Even better, there’s a link right at the top to an updated video released 3 years later that explains how to achieve the same thing following the removal of Rails Metal.

It’s clear Ryan Bates put a lot of love and attention into the whole site!

Using Git to Edit Prose

Git is great at comparing lines of code that have changed but not so good at individual words within a line or paragraph of text.

When diffing you can use git diff --word-diff to get more granular word and punctuation changes but you wonā€™t see white space changes.

Use git diff --word-diff-regex=. to see all changes at a more granular level.

You can see the changes that way but Iā€™m yet to find an easy way to split out individual changes on the same line into separate commits. Patch mode doesnā€™t work for this (itā€™s still whole lines at a time).

My goal was to take a fairly long document that Iā€™d made a number of different changes to (punctuation, grammar, spelling mistakes, wording changes, whitespace errors, etc) and commit the changes by type… one commit for all the spelling mistakes, one for all the whitespace changes and separate ones for each of the suggested wording changes. The reason for this is to allow the different commits to be accepted or rejected individually.

It gets very tricky when one line has multiple changes… a typo, some whitespace errors and a suggested change. I want each of those in different commits but I canā€™t easily just grab one word of the line.

So far, the best method I have found (e.g. to just fix the spelling mistakes) is to use git diff --word-diff-regex=. in one terminal window to see the individual changes, copy a whole line in my editor, discard the changes to that line, fix the spelling mistake again, save and stage that line, then paste the whole line back in with its other changes and save again.

The end result is the spelling fix is staged and the other changes to that line are saved in my working tree. Once Iā€™ve repeated that process for all the spelling mistakes Iā€™ll be able to commit and move on to one of the other fixes.

Overall Iā€™m not happy with this technique so Iā€™m going to research other options tomorrow.

After an interesting article on memory usage and bloating in Ruby I came across another article by the same author about the Annotate gem.

Annotate puts the relevant schema in your Rails models and tests as a comment so that you don’t have to keep referencing db/schema.rb

Today I Learned that to include a Ruby symbol in a YAML file it needs to be prefixed with !ruby/symbol

For example:

my_list_of_symbols:
  - !ruby/symbol one
  - !ruby/symbol two

becomes:

{ my_list_of_symbols: [:one, :two] }

Windows usage Venn Diagram

Sometimes I’m happy to be a late adopter of Ruby and Rails, other times I feel like I missed out on all the fun.

Anyway, today I heard of Rails Metal for the first time.

Yep, I’m linking to a blog post from 10.5 years ago! How’s that for a hot take?

Today I started learning about ActiveJob.

Thanks to a deprecation warning I’m also learning about Sidekiq, Redis and how (not) to store data in Redis :)

Short version:

Various (but widespread) adoption problems with Teams, SharePoint and OneDrive are a good reminder that less is more…

Googleā€™s offerings may have a shorter feature checklist but in my mind thatā€™s a good thing. The fundamentals are solid and the features they do have, work.