blake.app

TIL

Just thought I should try to write down at least one thing per day that I have learned trying to figure out some programming issue. These are intended to be small little posts that I can easily refer back to and hopefully you also find them helpful.

In ruby when you want to get a value out of a hash you can use h.fetch('key') instead of h.['key'].

I ran across .fetch while debugging this code:

and found out that it raises a KeyError exception when it can’t find the key in a hash.

The cool thing is that the next day I was fixing a bug in some other internal program of ours and needed to display a helpful error message if the key was missing from a hash and because I took the time to understand the code I was working on the previous day I knew exactly what to do!

def hello(key)
  @h.fetch(key)
rescue KeyError
  puts "Error: Could not find key"
  exit 1
end

So this is the 2nd day in a row now that I looked this up, so I thought I should post it here. What I want to do when I finish up working on a code change is clean up any files that I have made changes to, but that I don’t actually want to commit.

I’m in the habit of using git add . so I don’t really want to just do git add <file> for each file that I want to keep, I’d rather do the opposite. But what is the opposite of git add <file>?

At first I found this answer, which does do what I want:

git stash push -m asdf <file>

which will stash each file you specify. The thing with this command though is that I have no intention of ever popping this files off of the stash and I have to specify an arbitrary name for the stash.

I much prefer this method:

git checkout -- <file>

It is simple enough I can just remember it and it discards any changes to files that I don’t want to commit. Once I’ve removed all the files I don’t want to commit I can safely run git add . and then commit my changes.

I use silver-searcher (ag) a lot for searching the contents of files. Because our code base consists of ruby and js files I often want to search based on file extension. This can be done like so

ag <search-term> --ruby

or

ag <search-term> --js

I stumbled upon ruby refinements today while looking into the xorcist gem. They are basically a safer alternative to monkey patching.

require 'xorcist'
require 'xorcist/refinements'
using Xorcist::Refinements

a, b = 'a', 'b'
a.xor(b)
a.xor!(b)

Here are some blog posts about refinements that I found:

In a Gemfile I’ve always seen require have a value of false, but I wasn’t sure what this syntax was doing:

gem 'discourse_image_optim', require: 'image_optim'

I thought it meant that it would also install the image_optim gem, but if you run gem list | grep image_optim it only lists our discourse_ version:

blake@pop-os ~/code/discourse (master) $ gem list | grep image_optim
discourse_image_optim (0.26.2)
blake@pop-os ~/code/discourse (master) $

But, turns out, according to the docs

If a gem’s main file is different than the gem name, specify how to require it.

gem 'rack-cache', :require => 'rack/cache'

So, because we forked image_optim and didn’t rename anything we still need to call it by its original name.