Today I Learned

A Hashrocket project

247 posts by jakeworth @jwworth

Mass-Delete Git Tags

Building off this post:

I'm an advocate of Semantic Version tagging. It communicates to a team about every deploy and makes that rare rollback easier. So when does it not make sense to use a tag?

When you're the only developer (nobody to communicate with except yourself), and also using a platform like Heroku that tags every release (your tags are redundant). This the case with my blog, so today I set out to delete all my Git tags.

First, delete them remotely (assuming a remote named origin):

$ git tag | xargs git push --delete origin

We also have to delete our local tags, or a tag push with create them again on the remote:

$ git tag | xargs git tag -d

$ git tag now returns nothing, and there are no remote tags.

Vim Insert Mode Filename Completion

Today I learned that Vim has native filename completion. The command is CTRL-X CTRL-F in insert mode. Here it is in action:

This is useful for requiring files in different directories. See :help i_CTRL-X_CTRL-F for more information.

h/t Brian Dunn

Netrw Special Command

Building off this previous post, today I learned a new command in Netrw: the 'special command'.

When navigating, enter x over any file, and your operating system will open it with its tool of choice (Preview for images and Finder for directories on a Mac, etc.). This is great for exploring a directory.

From the Netrw help:

Certain files, such as html, gif, jpeg, (word/office) doc, etc, files, are
best seen with a special handler (ie. a tool provided with your computer's
operating system).  Netrw allows one to invoke such special handlers by:

        * when Exploring, hit the "x" key
        * when editing, hit gx with the cursor atop the special filename
          (latter not available if the g:netrw_nogx variable exists)

Send SQL to a Tmux Window

Hashrocket.vim provides a mapping that is awesome:

autocmd FileType sql nmap <buffer> <leader>t :<C-U>w \| call Send_to_Tmux("\\i ".expand("%")."\n")<CR>

With this command, if you're editing an SQL file in a Tmux session, run <leader>t from normal mode, and your file will be read into the session and window of your choice. If there's a psql session listening there, you've got a fast way to iterate on an SQL statement from Vim.

The command even writes the file for you before sending the SQL.

When Was This File Added to Version Control?

I learned a helpful Git command today. To determine when a file was added to version control, run the following:

$ git log --follow --diff-filter=A <filename>

This returns the Git history, following files through renames, filtering on when a file was added to version control. Here's the output for the README of 'Today I Learned':

$ git log --follow --diff-filter=A README.md
commit 9a7984a48db19489bb4113378298ddaa97121c7a
Author: Jake Worth <dev+jwworth@hashrocket.com>
Date:   Sat Mar 28 12:52:19 2015 -0400

    Add a basic README

Useful for explaining mystery files in the repository 🔎.

Related File in Rails.vim

Rails.vim is a staple of our Hashrocket workstations. It continues to surprise me.

Today I discovered the :R (related) command, which is a counterpart to the :A (alternate) command. :R looks for the file related to your current buffer.

This command is sophisticated. Assuming you're following Rails conventions for file organization, :R over most templates will open the associated controller, with your cursor on the line where the action that corresponds with the view name (show for a template called show.html.erb) is defined. The same thing works in reverse; :R over the show method leads you back to show.html.erb.

Re-mark a Word as Bad

Vim's spell checking feature is pretty great. I use it as a default for .md and .rdoc files on my machine.

Sometimes it incorrectly marks technical words like 'ExUnit' as bad (misspelled). To fix this, I type zg over the word in normal mode, which adds it to a list of white-listed words that are no longer considered bad.

The opposite of that command is zw, which comments out the line in the dictionary file. Run :runtime spell/cleanadd.vim to clean up those comments.

Revealing Rails Scopes

I've been working on some Rails code that brings in ActiveRecord models from multiple gems. Often these models have default scopes, that bane of a legacy Rails codebase, and figuring that out requires source diving one or more gems. Today I hacked my way to a faster solution: just read the SQL Rails generates.

Here's a post without a default scope, and then one with a default scope:

pry(main)> Post.all.to_sql
=> "SELECT \"posts\".* FROM \"posts\""
pry(main)> Developer.all.to_sql
=> "SELECT \"developers\".* FROM \"developers\" ORDER BY \"developers\".\"username\" ASC"

I see you, ORDER BY.

RSpec Covers a Range

Today I used a feature of RSpec I've never used before, cover.

cover returns true if it's argument is covered by the given range:

expect(0..1).to cover(order.risk_score)

In my use case, I had an attribute risk_score that is calculated by a third-party API. It should always be between zero and one, but it changes on every test run because the API considers the test user more and more risky each time. cover allowed me to test this attribute, and the underlying logic, in a flexible way.

Logrotation for a Rails App

This week I did a some Linux server logrotation for a Ruby on Rails application. log/your_log.log can get large on a server with traffic, and sometimes we must control how long to retain data.

Here's the basic configuration file I wrote, with comments:

# Logrotater:
# - Daily
# - Timestamped
# - Doesn't error on missing log files
# - Keeps seven copies
# - Truncates log files (allows Rails to start writing 
#  to the new log file without a restart)

/var/app/current/log/your_log.log {
    daily
    dateext
    missingok
    rotate 7
    copytruncate
}

There are many other options. Check out man logrotate on a Linux machine for more info.

How Rails Responds to `*/*`

Yesterday I fixed a bug in TIL. This application has a Twittercard, but it's never worked. Twitter's card validator confusingly claims the site lacks Twitter meta tags.

After experimenting, I realized that when cURL-ing our site, the response type is application/json. Why is Rails giving me JSON?

When an HTTP request's accept headers equal */*, any MIME type is accepted. And, when a respond_to block is present:

Rails determines the desired response format from the HTTP Accept header submitted by the client.

Determined how? I learned that the first MIME type declared is used for */* requests.

Notice the difference (HTML first):

# app/controllers/posts_controller.rb
 def index
    @posts = Post.all
    respond_to do |format|
      format.html
      format.json { render json: @posts }
    end
  end

Request/response:

$ curl -vI localhost:3000/
...
> Accept: */*
>
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...

JSON first:

# app/controllers/posts_controller.rb
 def index
    @posts = Post.all
    respond_to do |format|
      format.json { render json: @posts }
      format.html
    end
  end

Request/response:

$ curl -vI localhost:3000/
...
> Accept: */*
>
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...

Reversing the order (HTML first) solved the issue.

Deprecated Dynamic Actions

Rails routes have supported dynamic actions in the past, like this:

# config/routes.rb

 get 'ui(/:action)', controller: 'ui'

The 'Today I Learned' application uses code like this to create design templates.

This will be deprecated in Rails 5.1. If you want to address the change now, while still supporting a variety of routes, one solution is to name them explicitly:

# config/routes.rb

namespace 'ui' do
  %w(index edit show).each do |action|
    get action, action: action
  end
end

Change Time to UTC or Local

Today I discovered yet another cool feature from the vim-speeddating plugin.

To change a time in a Vim buffer to UTC, type d<C-A> with the cursor over the word. For local time, d<C-X>.

A use case would be setting a created_at time in a test, or time-stamping a manual log entry.

Break Up Lines with Splitjoin

One style-guide idea I try to maintain is sticking to a reasonable line length. 72 characters, 80 characters, whatever your preference; long lines are hard to read. They're a code smell. They need to have a reason for existing.

A task I find myself repeating a lot to achieve this is breaking apart Ruby blocks and hashes into multiple lines, with a combination of jumping forward, entering insert mode, and hitting enter. Turning this:

FactoryGirl.create(:developer, username: 'jake_skid', superpower: 'technical writing and style-guide compliance')

into this:

FactoryGirl.create(:developer, {
  username: 'jake_skid',
  superpower: 'technical writing and style-guide compliance'
})

This task has been automated for me by the Splitjoin plugin for Vim, which is included in the Hashrocket dotfiles. Typing gS in normal mode over the first example turns it into the second example. It's opinionated, and probably won't satisfy every tangent of your personal style (I'd leave off the curly braces and add a trailing comma, for instance). But it's already saved me a lot of time.

h/t Dorian Karter

Appended Pathnames

Check this out:

[1] pry(main)> Rails.root.join("app", "assets") == Rails.root/"app"/"assets"
true

The right hand side of the double equals works because / is aliased to + in Ruby's Pathname class. It's valid syntax for building a pathname.

Confuse your friends!

h/t Brian Dunn

Documentation

Understanding Github's Language Calculations

Ever noticed this at the top of a Github repo?

This filetype percentage is calculated by Github's Linguist project.

There's just one problem: 'Today I Learned' isn't a JavaScript project; it's a Rails application. I would expect the majority of the files to be Ruby files. Labeling 'Today I Learned' a JavaScript project misrepresents it to the Github community.

I found several techniques to correct the Linguist evaluation; this pull request explains one I tried in greater detail. TL;DR – once I moved some vendored JS files into a directory with a name that Linguist ignores (ace-builds/), the calculation started to look more like a Rails app.

Here's the updated header:

Custom Phoenix Validations

Today I learned how to write a custom Phoenix model validation. It came from the Phoenix port of this very application, which requires that posts be 200 words or less.

Phoenix doesn't have a word length validation, so I had to make my own. Here it is, minus some irrelevant lines of code:

# web/models/post.ex

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:title, :body, :channel_id])
  |> validate_length_of_body
end

defp validate_length_of_body(changeset) do
  body = get_field(changeset, :body)
  validate_length_of_body(changeset, body)
end

defp validate_length_of_body(changeset, body) do
  if length(String.split(body, ~r/\s+/)) > 200 do
    add_error(changeset, :body, "should be at most 200 word(s)")
  else
    changeset
  end
end

When the post body is greater than 200 words (as defined by splitting on whitespace characters), the validation adds an error to the body field that mimics the errors Phoenix provides for character-length validation failures. Including the (s), which I kind of like.

When the body is short enough, changeset is returned from the function of the same name, a form of success.

Pattern matching FTW.

Vimscript String Coercion

An unique feature of Vimscript is coercion of strings into integers.

Here's an example:

:echom "six" + 6
:echom "6six" + 6
:messages
6
12

Our messages show that the first string was coerced to 0 (0 + 6 = 6), and the second string was coerced to 6 (6 + 6 = 12).

Following this logic a little further, because 0 is falsey and 1 (or greater than 1) is truthy, our first string is falsey and our second string is truthy.

Spellcheck Certain Filetypes

I don't like misspellings in my documentation, yet make a lot of them. Spelling is disabled in all my buffers by default; I turn it on when reading or editing docs. When I forget to do so, it's easy to miss typos.

While reading Learn VimScript The Hard Way I figured out a better solution to this problem. This now lives in my ~/.vimrc.local:

augroup spellcheck_documentation
  autocmd BufNewFile,BufRead *.md setlocal spell
  autocmd BufNewFile,BufRead *.rdoc setlocal spell
augroup END

Anytime a markdown or RDoc file is created or read, I set a local configuration to turn spelling on. This has already proved invaluable after only a day or two.

Exclamation Point Toggles Vim Booleans

I have Vim line numbers turned on as a default, but sometimes I turn them off for better reading.

Today I learned that instead of :set nonumber (and the corresponding :set number) we can toggle any Vim boolean option with an exclamation point.

So, if line numbers are 'on', :set number! (or the even shorter :set nu!) turns them off, and vice versa.

Exit BufExplorer with `q`

One of my favorite Vim plugins is BufExplorer. It's indespensible if buffers are part of your Vim workflow.

Today I was reminded that you can exit your BufExplorer window with just q; no :q required. One keystroke instead of four; enjoy your extra free time.

h/t Josh Branchaud

See :help BufExplorer for more information.

Filter Your Git Diffs

Sometimes reading a git diff can be a big task. Imagine working through a big file cleanup, removing and modifing hundreds of files, and one of those modifications had an undesireable side effect. How can we filter the noise to find the problem?

git diff has a --diff-filter flag for this purpose. The specific command I used today was:

$ git diff --diff-filter=M HEAD~5 > changes.txt

This showed only modified files over the previous five commits, excluding thousands of deleted references. By directing the output to a file and visually scanning, I quickly found the problem— a forced redirect to HTTPS on the development server.

See git diff --help for more info.

Push Variables to Heroku

If you use Heroku to deploy your apps, I have a great command to try.

Included in the Heroku toolbelt command-line interface is heroku config:push.

This command pushes your local environmental variables, defaulting to a file called .env in your root directory, to any Heroku remote. It favors existing remote configs in the event of a collision.

No more copying and pasting to the command line, or pointless typos while setting remote configs.

Bonus: also check out heroku config:pull— equally useful.

Ruby Arguments Can Reference Other Arguments

I love the dark corners of Ruby. Today we discovered this one by basically guessing that it might work:

def foos(foo, bar = foo.upcase + "!")
  puts foo
  puts bar
end
2.3.1 :001 > foos('foo')
foo
FOO!
 => nil

That's right; bar references another argument, foo. And we can also call a method on it. And concatenate it with a string, because, why not? The 'principle of least surprise' strikes again.

h/t Brian Dunn

Rails Database Migration Status

Wondering if you've run the latest database migration? Wonder no more. There are better ways to find out this information than blindly running the migrations or waiting for your app to crash.

A handy command built into Rails is rake db:migrate:status. Here's some sample output from my blog's development PostgreSQL database:

% rake db:migrate:status

database: worth-chicago_co_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20150422174456  Create developers
   up     20150422174509  Create authem sessions
   up     20150422200749  Create posts
   up     20150423152139  Add url slugs to posts
   up     20150628171109  Add constraints to posts and developers

Knowledge is power!

Append an RSpec Failure Message

Have you ever wanted to customize an RSpec failure message? It's possible, but we lose the original message. What if we want both?

Here's one technique:

begin
  expect(actual).to eq(expected)
rescue RSpec::Expectations::ExpectationNotMetError
  $!.message << <<-MESSAGE

You broke it.

Maybe you deleted the fixtures? Try running `rake db:create_fixtures`.
  MESSAGE
  raise
end

This rescues the failure ExpectationNotMetError, then shovels our HEREDOC string onto the message of $!, a built-in Ruby global variable representing the last error. Then, we raise.

The result is our RSpec error, with the provided message, followed by our custom text.

Chrome Developer Tools Undo

A really nice feature of Chrome Developer tools is undo. It's the standard ⌘ + Z on a Mac, allowing you to walk back your changes in the Elements editor, like so.

Great for HTML and CSS experimentation.

Vim Asterisk Search 🔎

My favorite thing about Vim is how deep it goes. I learn new things every day, even after several years of daily use. Asterisk (*) search was one such example from this week.

Typing * over any word initiates a search of the current buffer for the next instance of that word. It actually transfers the folllowing into the command bar, with word boundaries included (hovering over the word foo):

/\<foo\>

This is vanilla Vim, from the patterns library.

A Better File Wiper 📂

A tried-and-true debugging technique is to tail the test log:

$ tail -f log/test.log

When the output gets noisy, we might 'wipe' the log by removing it, so that it only contains the output from a single action:

$ rm log/test.log && rspec spec/features/user_logs_in_spec.rb

A better way to do this is to overwrite the file, like so:

$ echo '' > log/test.log

This wipes the file without replacing it, which preserves its serial number. It's less destructive, and allows other processes interacting with the file to finish their work.

Here's an example of this principle in action, using ls -i. Notice how the file's serial number changes when we replace the file, but not when we ovewrite it.

$ ls -i *.txt
27232432 foobar.txt
$ rm foobar.txt
$ touch foobar.txt
$ ls -i *.txt
27232453 foobar.txt
$ echo '' > foobar.txt
$ ls -i *.txt
27232453 foobar.txt

h/t Brian Dunn

Rails' `Hash#except`

A cool feature provided by Rails is the #except method on Hash. This function removes a key-value pair from a hash.

Let's remove a Rails parameter, the most obvious use case I can think of:

[1] pry(#<SessionsController>)> params
=> {"utf8"=>"✓",
 "user_login"=>{"email"=>"", "password"=>"general"},
 "controller"=>"sessions",
 "action"=>"create"}
[2] pry(#<SessionsController>)> params.except(:utf8)
=> {"user_login"=>{"email"=>"", "password"=>"general"},
 "controller"=>"sessions",
 "action"=>"create"}

And the source code:

[1] pry(#<SessionsController>)> show-source Hash#except
From: /Users/dev/.rvm/gems/ruby-2.2.5/gems/activesupport-4.2.7.1/lib/active_support/core_ext/hash/except.rb @ line 9:
Owner: Hash
Visibility: public
Number of lines: 3

def except(*keys)
  dup.except!(*keys)
end
[2] pry(#<SessionsController>)> show-source Hash#except!

From: /Users/dev/.rvm/gems/ruby-2.2.5/gems/activesupport-4.2.7.1/lib/active_support/core_ext/hash/except.rb @ line 17:
Owner: Hash
Visibility: public
Number of lines: 4

def except!(*keys)
  keys.each { |key| delete(key) }
  self
end

Thanks Rails!

Ruby $!

This week I enjoyed using Ruby's built-in global variables, including $!. $! refers to the last error that was raised, and is useful in lots of different contexts such as Rake tasks.

Here it is in action:

:001 > begin; raise NameError; rescue; puts "The error we raised was #$!."; end
The error we raised was NameError.

And a list of these global variables:

https://github.com/ruby/ruby/blob/trunk/lib/English.rb

For a slightly less bare-metal implementation, require this library and utitlize the friendly names:

:001 > require 'english'
 => true
:002 > begin; raise NameError; rescue; puts "The error we raised was #$ERROR_INFO."; end
The error we raised was NameError.

:Gbrowse!

One of my favorite developer-to-developer communication tools is :Gbrowse, provided by vim-fugitive. This command opens your current Vim buffer, or a line or range, in the hosting provider specified by your remote. It's irreplaceable for quickly sharing code worthy of discussion.

Take this command to the next level with :Gbrowse! which puts the URL your browser would open into your paste buffer. From there, paste away into your project management tool or chat client, getting everybody on the same (web)page.

Postgres Intersect

Today I got to see some great SQL debugging that included the use of intersect to compare two datasets.

intersect computes the set intersection of the rows returned by the involved select statements.

Here's a simple implementation:

dev=# select generate_series(1,1000) intersect 
  select generate_series(10,15);
 generate_series
-----------------
              11
              12
              10
              15
              13
              14

Like a lot of things in Postgres, the order seems deterministic, but not predictable.

Docs

Show Changes, Excluding a Directory

This is a command we figured out recently that I'm proud of:

$ git diff --name-only new-branch..master  -- . ':!spec'

This printed a list of all the files that differed between our new-branch and master, excluding changes in the spec directory. From here you can check out the files in either state and explore.

Chaining Vim Commands ⛓

You can chain Vim commands together using |. Here's an example:

:help fugitive | resize 10

This will open the help page for Vim-Fugitive, and then resize the current window.

Here's some real-life code I execute frequently:

:Gread | w

This empties the buffer and reads it at the last git revision, then writes the file. Very useful for rapid experimentation.

See :help :bar for more information.

Cucumber Suite Hooks

Adding hooks that run before and after your RSpec test suite looks like this:

# spec/helper/spec_helper.rb

RSpec.configure do |config|
  config.before(:suite) do
    My::Service.build!
  end

  config.after(:suite) do
    My::Service.tear_down!
  end
end

But for Cucumber, the API isn't quite as obvious. I found some interesting discussion online about this subject, and eventually settled on the following:

# features/support/env.rb

My::Service.build!

at_exit do
  My::Service.tear_down!
end

Anything in features/support/env.rb gets run before the Cucumber test suite, so the first method call functions like a before suite block. at_exit is Ruby Kernel and runs when the program exits. This implementation works roughly the same as a before and after block.

View your Github Project's Forks

Today I clicked on the number next to the fork count on a Github project, and landed on this page (TIL used as an example):

https://github.com/hashrocket/hr-til/network

This chart is pretty cool— it visualizes the recent forking activity around your project, and gives you insight into activity happening downstream on different forks.

Capitalized Letter is the Default

Today I learned something fun about command line interfaces— when presented with a list of choices such as yes, no, or quit, the capitalized choice is the default in many Unix-based CLIs.

Here's some aptitude:

% sudo apt-get install whatever
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  python-cssselect python-glade2 python-pyquery
0 upgraded, 3 newly installed, 0 to remove and 43 not upgraded.
Need to get 497 kB of archives.
After this operation, 2,207 kB of additional disk space will be used.
Do you want to continue? [Y/n]

The interface waits for your Y ('yes') or n ('no').

Because 'yes' is capitalized, it's the default, simply pressing ENTER is the same as pressing Y, then ENTER. Enjoy your extra keystrokes!

Commit Message Templates

We set something up on a recent project that I really liked.

In the midst of writing a bunch of tests, I realized I was starting every commit message with Test, followed by a description of the feature. Test login, Test that bots are redirected, etc. Typing the same word over and over is redundant, and it adds up quickly.

We paused and set up a commit template for the project.

Here's the file we made (~/.git_commit_template.txt):

Test 

And the command in the project directory:

$ git config commit.template "~/.git_commit_template.txt"

Our next commit message started with Test, so we just used CTRL-A to jump to the end of the sentence and start filling it in.

This does more than just save keystrokes. It reminds us that we have a format we want to stick to, and helps keep our commit message more uniform.

This could also be set globally, if you have a format you prefer to use on every project.

ExtractRspecLet

From the Hashrocket Vault...

Today I got to see the :ExtractRspecLet command from the vim-weefactor plugin. It does what the names suggests, converting this:

# spec/model/foobar_spec.rb

foo = FactoryGirl.create :foobar

To this:

# spec/model/foobar_spec.rb

let(:foo) { FactoryGirl.create :foobar }

It also moved the new let from inside my it block to right underneath my context block. Awesome!

h/t Josh Davey and Dillon Hafer

Vim Regex Word Boundaries

Today while writing a Vim regex to change every instance of it (ignoring larger matches like itemized), we stumbled upon Vim regex word boundary matching.

Given this file:

foo
foobar

The following Vim regex will match on both the first and second line:

:%s/foo/baz/g

But with word boundaries, we'll only match (and change) the first line, because only the first foo is a standalone word:

:%s/\<foo\>/baz/g

Spellcheck Attribute

Have you ever noticed formatting like this in a text field?

The browser knows that 'Today' and 'Learned' are misspelled... but how?

The answer is the spellcheck attribute. Set it to true to enable the spellcheck magic. Right click each word for suggestions, dictionaries, etc. (Chrome).

Spellcheck is enabled by default on Chrome, but you will have to set it explicitly on some or all versions of Firefox and IE. Learn more here:

http://caniuse.com/#feat=spellcheck-attribute

Capybara Find with Wait

Integration tests covering JavaScript features are a prime location for timing-related flickers. Often our implementation and expectations are correct, but the test gives up and bails before the desired behavior can be observed.

Patience!

With Capybara, one way around this is to just wait a little longer. This code:

find('.mj-modal iframe', wait: 5)

will wait for the iframe up to five seconds, overriding Capybara's default max wait time of two seconds. On certain test runs this can make all the difference.

Ruby's `gsub` with Block

Today I learned that Ruby's gsub method accepts a block. This seems useful for complex replacements.

2.1.0 :001 > "look at those potatoes".gsub(/p.*s/) do |match|
2.1.0 :002 >     match.upcase + '!!!'
2.1.0 :003?>   end
 => "look at those POTATOES!!!"

Documentation

View Source Repos on Github

A neat hack when browsing a Github profile is to view only source repositories with the 'Source' button.

This excludes repository forks, as might be used for open-source contribution, only showing original repos.

Return `MatchData` with `$~`

Check out this Ruby regex:

2.1.0 :001 > "totally gourmet" =~ /totally/
 => 0

There's a match at index zero. But what is the thing that actually matched? Enter $~:

 2.1.0 :002 > $~
  => #<MatchData "totally">

$~ stores the result of the last regex, and can be called later on. This is equivalent to the match method:

2.1.0 :003 > /totally/.match('totally gourmet')
 => #<MatchData "totally">

h/t Brian Dunn

Psql Command with Tuples Only

With psql, we can run any string command once and exit using the -c (command) flag. Here's an example:

$ psql hr-til_development -c 'select title, slug from posts limit 5';
                  title                   |    slug
------------------------------------------+------------
 Start rails server in production mode    | 97e26f5f68
 Enable ScreenSharing from a terminal     | 55dfe1a1a3
 Variable Hoisting in JavaScript          | eeedb8dda0
 Three ways to compile Elixir             | f2a423d1e1
 Indent and de-indent line in INSERT MODE | 8de0fb5d93
(5 rows)

If you are parsing the result, the headers can get in the way. This is where the -t (tuples only) flag is useful. Same query:

$ psql hr-til_development -tc 'select title, slug from posts limit 5';
 Start rails server in production mode    | 97e26f5f68
 Enable ScreenSharing from a terminal     | 55dfe1a1a3
 Variable Hoisting in JavaScript          | eeedb8dda0
 Three ways to compile Elixir             | f2a423d1e1
 Indent and de-indent line in INSERT MODE | 8de0fb5d93

Notice the headers and row count are gone. Toggle this in a psql session with the \t command.

Grep your Database 🔎

Wading through a database full of text (as might support a CMS) and feeling lost? Sometimes you gotta ditch the queries and just start grepping.

This Stack Overflow post sums up the idea. Here's a version of the command we used today to pick through a text-rich database:

$ curl `heroku pg:backups public-url -rproduction` | pg_restore | egrep -o '[a-z]+\.chicagocatlounge.biz'

This found, via a regex match, all subdomains of our target URL, in any text field of the production database. Pretty awesome.

Find Dead Code with Unused

Today I discovered a fascinating tool called Unused, written by Josh Clayton.

Unused leverages two of my favorite projects, Exhuberant Ctags and The Silver Searcher, to identify dead code. I installed it with homebrew.

Dead code is code that is never used by your application. It wastes electricity and mental bandwidth, and can hang around unnoticed for years. We need powerful tools to find and remove it.

Unused threw out a few false positives, as expected. Use with caution and a solid test suite.

The Unused website highlights several pull requests removing dead code from popular open source projects. I was able to use it on 'Today I Learned' itself. A small win:

https://github.com/hashrocket/hr-til/pull/101

Github Advanced Search Parameters

I really enjoy browsing Github. The search feature in particular is a fantastic way to stumble on interesting projects.

Search has an 'advanced' menu that lets you restrict your query. I've used it enough that I have some preferences that I enter directly into the search bar: is:issue is:open label:"help wanted" finds open issues actively seeking outside contributions. Not everybody uses labels, so removing that can yield even more results.

Add a language filter as a query parameter, and you're on your way to some good open source contribution opportunities. Drill down further with a search term, such as 'testing' or 'flicker'.

Filter Your Seed-Fu Seeds

Seed-Fu accepts two options that are really useful for narrowing the impact (and speed) of your database seeding.

You can seed only from a certain file or directory:

$ rake db:seed_fu FIXTURE_PATH=path/to/fixtures

Or, filter seeds based on matching filenames:

$ rake db:seed_fu FILTER=users,articles

h/t Brian Dunn & Josh Davey

`Enum.chunk_by`

I discovered a pretty cool Elixir function this weekend, Enum.chunk_by.

Backstory: I wanted to group a list of strings by equality, while preserving the list order.

Enum.chunk_by takes an enumerable and a function, and breaks that enumerable into an enumerable when the function returns a new or different result.

Here's a simple example:

iex> Enum.chunk_by(['A', 'A', 'A', 'B', 'A'], fn(l) -> l end)
[['A', 'A', 'A'], ['B'], ['A']]

Anytime l changes, a new list is created.

Slightly more complex:

iex> Enum.chunk_by([1, 2, 3, 4, 5], fn(n) -> rem(n, 3) == 0 end)
[[1, 2], [3], [4, 5]]

The function only returns something different (true) on 3, so 3 is assigned to its own list.

Ruby-Like `split` in Elixir

Elixir's split function is a bit different from the Ruby version you might be familiar with.

Here's Ruby's split:

2.1.0 :001 > "FOOBAR".split("")
 => ["F", "O", "O", "B", "A", "R"]

And Elixir's:

iex(1)> String.split("FOOBAR", "")
["F", "O", "O", "B", "A", "R", ""]

Whoa, what's that extra "" doing in there? Drink in the Elixir. A small amount of message board reading has led me to conclude this was very deliberate and isn't going to be changed.

Here's one way to get a Ruby-like split:

iex(1)> String.split("FOOBAR", "", trim: true)
["F", "O", "O", "B", "A", "R"]

Open Multiple Tabs with Vim

I like to use Vim to open many files at once. Today I discovered the -p flag to help with this process.

To open all the files in a directory in tab mode, use this command:

$ vim -p path/to/files/*

-o does the same thing in horizontal splits; -O in vertical splits.

When you're finished reading, :qall is a nice way to close the book.

Rails Generate, No Tests

Rails generators do a lot of things, such as adding boilerplate (assert true) tests.

Exclude these files with --no-test-framework:

$ rails generate model foobar --no-test-framework

An alternative would be setting this in your app's configuration; this is the more granular approach.

Share Highlighted Code

Today I learned a cool trick.

Select a range of code, enter command mode, and type Gbrowse:

:'<,'>Gbrowse

This opens Github in your browser with the range of code highlighted. Github support seems to be standard; I believe you can add other code hosting providers.

Here's a link I made with this command:

https://github.com/hashrocket/hr-til/blob/1bc38b724bb620b1672a9f525a4450f6d4f68b3c/app/controllers/sessions_controller.rb#L15-L18

This also accepts a line number:

:10 Gbrowse

Ruby's `__LINE__`

Debugging a tough problem, with terse, unhelpful error messages? Sometimes puts driven development can only take you so far.

A corner of Ruby I sometimes forget about are the double-underscore methods on Object. Today I learned a new one: __LINE__.

Here it is in the console:

2.1.0 :001 > puts __LINE__
1
 => nil
2.1.0 :002 > puts __LINE__
2
 => nil
2.1.0 :003 > puts __LINE__
3
 => nil

Try putting this above and below code you think might be causing an issue.

A new tool for my debugging toolbox. 🔨

Documentation

h/t Brian Dunn

Bracket Ranges

Today while making a bunch of throwaway directories, I tried this command in ZSH:

$ mkdir test_app/{1..5}

This tab-completed to, you guessed it:

$ mkdir test_app/1 test_app/2 test_app/3 test_app/4 test_app/5

Three cheers for laziness! It's useful to know you can use ranges this way (did not work in Bash).

Window to Tab

Sometimes I like to use Windows in Vim, and sometimes tabs. But switching from windows to tabs? That's pretty smooth.

If you have a bunch of windows open, CTRL-W_T moves the current window to a new tab.

Check out :help CTRL-W for a crazy list of similar Vim power tools.

h/t Brian Dunn

Toggle Mute in Hangouts (Mac)

During client calls, I mute and unmute my microphone dozens of times. Mute to listen and cut ambient office noises, unmute to speak.

Google Hangouts provides some shortcuts for this and other common activities. In particular, ⌘ + d toggles mute on a Mac.

Step your videoconferencing game up! 🖥

https://support.google.com/hangouts/answer/3112005

Invoke Elixir Functions with Apply

I had a weird problem yesterday: I wanted to pass a function into another function and then invoke it, all for the sake of a friendly API.

Elixir's apply to the rescue. Here's the rough implementation.

defmodule Example do
  def do_things(index, rotation, operator) do
    apply(Kernel, operator, [index, rotation])
  end
end

iex> Example.do_things(10, 20, :+)
30
iex> Example.do_things(10, 20, :-)
-10

apply also accepts your own functions:

defmodule Example do
  def do_things(index) do
    apply(__MODULE__, :make_bigger, [index])
  end

  def make_bigger(a) do
    a * 10000
  end
end

iex> Example.do_things(100)
1000000

The module name (Example) will work in place of __MODULE__, if you prefer. This seems like a pretty powerful feature.

Clean your Working Tree, Interactively

git clean is a great command. It's the best tool in the box for wiping out untracked junk files from your working tree.

This command has a noteworthy optional flag, -i, for interactive mode. This gives you the option to clean everything, select by number, ask each, and more. I see it as the reverse of git add -p— we get granular control over what stays and what goes.

Tab Completion in IEx

IEx has tab completion of library functions, just like IRB. To see all the built-in Stream functions, just type Stream. and hit TAB, and you'll get output like this:

iex(1) Stream.
Reducers        chunk/2         chunk/4         chunk_by/2
concat/1        concat/2        cycle/1         dedup/1
dedup_by/2      drop/2          drop_while/2    each/2
filter/2        filter_map/3    flat_map/2      interval/1
into/3          iterate/2       map/2           reject/2
repeatedly/1    resource/3      run/1           scan/2
scan/3          take/2          take_every/2    take_while/2
timer/1         transform/3     transform/4     unfold/2
uniq/2          with_index/2    zip/2

This is a nice feature when you're experimenting in the REPL.

h/t Micah Cooper

Open a URL from Vim

If you have Vim and Netrw, you can open a URL in your browser of choice, right from the editor.

Place the cursor on the URL and type gx.

This will invoke your file handler; open for OSX. As a result, it also works with file types such as images, GIFs, and videos.

Move a File with Netrw

Today I tried to move a file into a subdirectory using only Netrw commands, and it kind of worked.

Here's my abridged Netrw window as an example:

ilike-for-case-insensitive-data/
intro-to-hstore/
lateral-joins/
lateral_joins.md

My goal was to move the lateral_joins.md file into the lateral-joins/ directory.

First, I placed the cursor over the target directory and entered mt. This makes that directory the 'markfile target'.

Next, I moved the cursor over the markdown file, and entered mf to mark the file, followed by mc to copy the file to the marked target directory.

Finally, I deleted the original file with D.

Since this was a little confusing, I tracked my changes with watch git status running in a separate Tmux window. I haven't found a way to do this as a straight-up move.

Kill Tmux Session From Tmux

If you've ever wrecked a Tmux session (hello, $ cat my-favorite-binary) and needed to kill the session, you don't have to leave Tmux to do so.

We can kill the session right from the Tmux command line ([CTRL + z] is my Tmux prefix):

[CTRL + z] :kill-session

h/t Dorian Karter

`hd` in Guard Tests

The hd method in Elixir returns the head of a list. It's kind of like List.first, but raises an error on an empty list.

iex(0)> hd [1,2,3]
1
iex(1)> hd []
** (ArgumentError) argument error
    :erlang.hd([])

Browsing the docs, I learned something interesting: hd is allowed in guard tests.

Here's a contrived implementation of this behavior:

# example.ex
defmodule TestModule do
  def header(list) when hd(list) == 1, do: IO.puts "We did it"
end
iex(0)> TestModule.header([1,2,3])
We did it
:ok

When the guard's conditions aren't met, an error is raised:

iex(1)> TestModule.header([2,3,4])
** (FunctionClauseError) no function clause matching in TestModule.header/1
    iex:13: TestModule.header([2, 3, 4])

h/t Chris Erin & Micah Cooper

Shell History in IEx

Do you like Elixir, but want history in your interactive shell, just like Ruby and other languages? I've got you covered.

Check out erlang-history. It's a must-have.

Here's the abridged version:

$ git clone https://github.com/ferd/erlang-history.git
$ cd erlang-history
$ sudo make install

Fire up IEx and enjoy.

https://github.com/ferd/erlang-history

Restore a Heroku PG Backup From Another App

If your staging and production instances are both hosted on Heroku, you can restore your production Postgres database to your staging instance from the Heroku CLI. No posting the dump on AWS, no backing up to a local dump, etc.

$ heroku pg:backups capture -rproduction

This will print the name of your new backup; let's call it b234, and the production app name my-blog.

$ heroku pg:backups restore my-blog::b234 DATABASE_URL -rstaging

The databases are now in sync.

Nulls Last, Nulls First

Postgres query sorting has a great feature,nulls first/nulls last, that helps us specify where in a query result null values appear.

Nulls in Postgres are sorted as larger than any other value, so this is a descending sort containing null values (💀 == null):

example=# select * from users order by full_name desc;
  full_name
--------------
 💀
 💀
 💀
 Tracy Jordan
 Liz Lemon
 Jack Donaghy

Reverse the null position with nulls last:

 example=# select * from users order by full_name desc nulls last;
  full_name
--------------
 Tracy Jordan
 Liz Lemon
 Jack Donaghy
 💀
 💀
 💀
(6 rows)

Here's the opposite query, ascending:

example=# select * from users order by full_name asc;
  full_name
--------------
 Jack Donaghy
 Liz Lemon
 Tracy Jordan
 💀
 💀
 💀
(6 rows)

Now, reverse the null position with nulls first:

example=# select * from users order by full_name asc nulls first;
  full_name
--------------
 💀
 💀
 💀
 Jack Donaghy
 Liz Lemon
 Tracy Jordan
(6 rows)

Lots of ways to explore our data.

Access Last Executed Vim Macro

I love Vim macros. They can be a huge time-saver.

Today I learned a new way to access them: @@.

We can access any macro with @<letter>, where <letter> is the macro you've assigned.

@@ accesses your last executed macro. This is useful when you have assigned multiple macros.

h/t David Colgan

Heroku Commands By Remote Name

Programming is often a game of inches; a keystroke here, and hotkey there, and suddenly you are doing magical things.

In that spirit, I recently learned that you can run Heroku commands against a remote name (assuming a remote named production):

$ heroku run <command> -rproduction

Instead of like this, which I think is more common:

$ heroku run <command> --app today-i-learned-production

Add those keystrokes to the bank.

Frontmatter Date Affects Build

Middleman is an excellent choice for blogging. Combined with Frontmatter, we can do many things.

Today I learned that if you include a future date key in your Frontmatter, the file in question will be excluded from the build.

And so, today, this file would not be built with middleman build:

<!-- source/episodes/1/first_episode.html.markdown -->
---
date: 06-21-2016
---

This makes sense, but it was not intuitive to me and took some troubleshooting.

Vim Spelling Suggestions

Vim makes finding misspellings easy, with this command:

:set spell

You may need to adjust your color scheme to read the highlighted words. I like 'ron' for this purpose.

Once Vim has highlighted a typo, what then? What is the correct spelling?

Put your cursor over the word, and type z= for a list of suggestions. You can replace the word with the index number of your choice:

Change "tryin" to:
 1 "Tryin"
 2 "Trying"
 3 "Train"
 4 "Try in"
 5 "Tr yin"

h/t Dorian Karter

Tag a Commit

I ❤️ Git tags. But tagging is a manual process, and sometimes I forget to do it.

My old solution was to find the commit I deployed, check it out, tag it, and push the tags to the internet. There is a better way!

You can tag any commit from anywhere in the tree:

$ git tag v1.0.0 a795622
$ git push --tags

This will tag commit a795622 and push it to Github. A sample workflow, if your deploy was one commit in the past, would be:

$ git tag v1.0.0 HEAD~1

Reflect on Association

Integration tests should expose flaws in our Rails domain models and associations pretty well. Any remaining uncertainty can be remedied by familiarity with the methods (has_many, belongs_to), entity relationship diagrams, and good old trial and error.

But what if we want to explicitly check our associations in a unit test?

Here's one way, with reflect_on_association:

# app/models/hike.rb
class Hike < ActiveRecord::Base
  has_many :trips
end
# spec/models/hike_spec.rb
RSpec.describe Hike, type: :model do
  describe 'associations' do
    it 'has many trips' do
      ar = described_class.reflect_on_association(:trips)
      expect(ar.macro) == :has_many
    end
  end
end

Overkill? Probably. But it's nice to have.

Source code:

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/reflection.rb#L109

HTTP Request Methods Limiting Arguments

Check out this RSpec test from a Rails application:

# spec/controllers/chapters_controller_spec.rb
describe ChaptersController do
  describe '#create' do
    it 'creates a chapter' do
      expect do
        post :create, chapter: FactoryGirl.attributes_for(:chapter)
      end.to change(Chapter, :count).by(1)
    end
  end
end

The code after :create will soon be deprecated.

5.0+ versions of Rails will only accept keyword arguments for ActionController::TestCase HTTP request methods.

Here's that same test, minus the deprecation warnings I encountered upgrading to the first Rails 5 release candidate:

# spec/controllers/chapters_controller_spec.rb
describe ChaptersController do
  describe '#create' do
    it 'creates a chapter' do
      expect do
        post :create, params: { chapter: { title: 'Change', body: 'Change is coming!' } }
      end.to change(Chapter, :count).by(1)
    end
  end
end

Create Database from a Template

Today I got to see Postgres' createdb invoked with a specified template, as such:

$ createdb -T prod_dump myapp_development

The -T feature flag corresponds to the TEMPLATE modifier in a SQL CREATE DATABASE statement. In the example above, this will create myapp_development that is a deep clone (structure and data) of prod_dump.

For more info, see:

$ man createdb

and:

$ psql
user=# \h create database;

h/t Brian Dunn

Open a Pull Request from the Command Line

Do you open source? If so, then check out hub. It enhances various Git commands, making OSS contribution and project management a lot easier.

Today I learned how to open a pull request from the command line. This is the base command:

$ git pull-request

This opens an editor where you can add more information, and see your branch and your target branch. Change the target branch with the -b flag.

Once installed, get more info here:

man hub

`CTRL` commands in Chrome's Address Bar

The Hashrocket Dotmatrix binds some of the UNIX CTRL- commands to commands in Chrome's address bar. Here are a few examples:

  • CTRL-a to move cursor to the beginning of the line
  • CTRL-e to move cursor to the end of the line
  • CTRL-b to move the cursor one space backward
  • CTRL-f to move the cursor one space forward

There are more to try; some work the same as they do in the command line, and some work differently.

Here's the code that makes this possible.

h/t Brian Dunn

Rust Array Access is Bound Checked at Runtime

Today I encountered a feature of Rust that I hadn't seen before— uses of array subscript notation ('array[n]') are checked at runtime to ensure they fit into the bounds of the array.

Here's a passing test I wrote to demonstrate:

// src/lib.rs
#[test]
#[should_panic(expected="index out of bounds: the len is 3 but the index is 5")]
fn array_access_is_bound_checked_at_runtime() {
    let elements = ["Wind", "Fire", "Water"];
    assert_eq!("Wind", elements[5]);
}

'Such errant access is the source of many bugs in other systems programming languages.' —The Rust Programming Language

More information:

https://doc.rust-lang.org/book/primitive-types.html#arrays

The Rust Docs Appear

The The Rust Programming Language is a great introduction to the Rust Language. But what if I want to read the book offline?

Today I learned that if you have Rust installed, you have the documentation locally, via this pull request:

https://github.com/rust-lang/rust/pull/23279/files

Here's the starting point (Unix):

$ open /usr/local/share/doc/rust/html/book/README.html

Execute this command and start reading.

rvm get master

Today while upgrading Rubies with RVM, I learned something— you have to go outside rvm get stable && rvm list known to see all the Ruby versions available.

When I ran these two commands on my machine, the newest Ruby listed was 2.3.0. I happen to know this is not correct; 2.3.1 was released last month.

An alternative is to use rvm get master && rvm list known. The master branch revealed the newer release. Interestingly, I was still able to install 2.3.1 via RVM before I found this solution, I just couldn't see that it was available.

The release manager for RVM explains:

http://stackoverflow.com/questions/12650164/update-rvm-list-known#answer-12650963

Add a Comment in Postgres

Today I learned about a neat Postgres feature, commenting. Here is a statement adding a comment to a table:

hr-til_development=#  comment on table developers is 'these are the authors';
COMMENT

Let's check it out:

hr-til_development=# \dt+ developers;
List of relations
-[ RECORD 1 ]----------------------
Schema      | public
Name        | developers
Type        | table
Owner       | jwworth
Size        | 16 kB
Description | these are the authors

According to the documentation, you can comment on many things. Use this wherever you feel a comment is necessary or appropriate.

http://www.postgresql.org/docs/current/static/sql-comment.html

h/t Chris Erin and Jack Christensen

How long have I been working on this Project?

Today I was thinking back on my time on a project, and wanted to see how long I'd been assigned to it. We've been on this project for a while, so traversing the Git log would require precision.

My solution:

$ git log --author="\(jwworth\)" --reverse

We use go-pear to set Git authorship for pairs; as a result my username 'jwworth' could be in several locations in the text of the author email. Luckily, the --author flag matches regular expressions.

Create Migrations Faster with Vim-Rails

Not only can we create database migrations with vim-rails, it's faster than using a generator. I counted the steps today and realized I was wasting precious keystrokes by underutilizing this great plugin.

Here's how I was setting up a migration:

  • Generate the migration:
$ rails g migration add_diameter_to_wheels
  • Load the migration in Vim with :Emigration (vim-rails)
  • Replace change method with up and down methods

Here's my improved method:

  • Generate a migration (in Vim) with :Emigration AddDiameterToWheels!
  • Create up and down methods

Less steps and characters, and best of all, we never have to leave Vim.

h/t Chris Erin

Vim Configuration Files by Directory

I have Vim line numbers enabled (:set nu) as a default, but I was working on a project recently where the line numbers weren't helpful. I wanted to disable them in that directory only, without changing my default setting.

One way to do this is to enable a local Vim configuration file. Here's how you do that:

" ~/.vimrc
set exrc

This enables the reading of .vimrc in the current directory.

Caveat: you should also add the following:

" ~/.vimrc
set secure

When this setting is enabled, :autocmd, shell, and write commands are not allowed in your local .vimrc.

Enabling local Vim configurations give a lot of power to any local configuration file. For instance, you could clone a Git repo with a checked-in .vimrc, and if you open Vim in that directory, any commands in that configuration will be executed. Use with caution.

More info:

:help 'exrc'
:help 'secure'

h/t Josh Branchaud

Get Vim Help for Current Word

Some Vim users may be familiar with K, which runs a program to lookup the keyword under the cursor. If not, try typing K over puts and watch the magic happen.

I wanted the same functionality for Vimscript keywords, so I added this mapping to my ~/.vimrc:

nnoremap <F1> :help <C-r><C-w><CR>

This maps F1 (or your key of choice) to, basically, run 'help' followed by whatever word is under the cursor, in normal mode. After sourcing your configuration file, you can try it on nnoremap— you should see the corresponding help page from map.txt.

Vim Cursorline

Yesterday I learned that Vim has a feature called the Cursorline.

Cursorline highlights the screen column of the cursor. It's useful for reading dense code like raw SQL or minified anything. It will also make screen redrawing slower.

Activate this feature with :set cursorline or :set cul. Deactivate with :set nocursorline or :set nocul. As with anything Vim, you can add it to your ~/.vimrc if you want to have it on by default.

vim-unimpaired gives us a mapping for this. [oc turns it on; ]oc turns it off.

See :help cul for the Vim feature, and :help [oc for the plugin.

Choose Your Own RSpec Command

We use vim-turbux to quickly iterate on Ruby tests. But we hit an issue setting up a project on Ubuntu 14.014 that had not been developed in a Linux environment before— Webkit tests there require the Xvfb library. Leaving out the xvfb-run wrapper raises a connection error in test.

Luckily, you can customize vim-turbux commands for each test framework.

Add this to your ~/.vimrc.local:

" ~/.vimrc.local
let g:turbux_command_rspec  = 'xvfb-run -a rspec'

Any RSpec test sent to the terminal window now includes the wrapper library.

Documentation

h/t Dorian Karter, Chris Erin, and Josh Davey

Toggle Vim Syntax Highlighting

Something I found memorable about Steve Klabnik's Ancient City Ruby 2016 talk was the Vim slides. He did something on-the-fly that caught my attention: disabling Vim syntax highlighting.

Syntax highlighting is useful. As Vim users we try to always have it— when I'm learning a new programming language, one of the first things I do is install the corresponding Vim plugin. It makes my code easier to read and write.

But sometimes it works against you. Code on a projector, code in certain languages, or code that exposes a highlighting edge case or bug in your Vim plugin, may require a different (monochrome) perspective.

:syntax off and :syntax on is all it takes.

See :help syntax for more information.

JavaScript Implied Global

Here is a common Ruby technique:

$ me = myself = 'rubyist'
$ me # => 'rubyist'
$ myself # => 'rubyist'

Let's try something similar in JavaScript.

var func = function() {
  var me = myself = 'rubyist';
};

This declares two local variables, me and myself, set to 'rubyist', right? As I learned today, no.

Variables in JavaScript are implied to be global. We must declare them as local with the var keyword. Thus, this function assigns, from right to left, myself as a global variable (because it isn't scoped on its own with var), then me as a local variable. Check it out:

$ func()
=> undefined
$ me
=> Uncaught ReferenceError: me is not defined
$ myself
"rubyist"

Define each variable explicitly and keep your global scope clean.

Variable Hoisting in JavaScript

I while back I wrote about variable hoisting in Ruby. This is when the value of a variable is 'hoisted' to the top of its scope with value nil, rather than left undefined, even if that variable is protected from ever being declared by (for example) an always-false conditional.

Today I learned that JavaScript shares this behavior.

Here's an example. Let's declare two global variables:

$ validGlobal = 'we need this';
=> "we need this"
$ questionableGlobal = 'aggressively scoped';
=> "aggressively scoped"

Then, make a function that declares a local variable with the same name as one of our globals:

$ var example = function() {
  console.log(validGlobal);
  console.log(questionableGlobal);

  var questionableGlobal = 'uh oh';

  console.log(questionableGlobal);
}();

=> "we need this"
=> undefined
=> "uh oh"

validGlobal logs its global value, as expected. But because questionableGlobal is also declared as a local variable in this scope, when we try to log it before that declaration occurs, it returns undefined, rather than the global value. This is to protect us from raising a ReferenceErrorquestionableGlobal has been 'hoisted' like a pirate flag.

This is a noteworthy feature of both Ruby and JavaScript.

View a File In Another Git Snapshot

Have you ever wondered: 'what does this file look like on the master branch?' vim-fugitive to the rescue.

This command will open our Gemfile as it exists on the master branch:

:Gedit master:Gemfile

And the same file, in the HR-TIL repo, initial commit:

:Gedit b4da33:Gemfile

This also works with tags, and includes split, vertical split, and tab variations— I like :Gsplit the best.

Install vim-fugitive and see :help Gedit for more information.

Rerun Failed Cucumber Tests

An underused trick in Cucumber is the rerun format.

Run your suite like so:

$ cucumber -f rerun -o rerun.txt

This runs your tests with the rerun formatter, sending the output to rerun.txt. After breaking a test, here's my generated file:

$ cat rerun.txt                                                                                                                                                 
features/visitor_views_posts.feature:9

Now we can run again against just the failing example!

$ cucumber @rerun.txt

Use this to drill down through a giant integration test suite.

How would this command be interpreted?

A nice alternative to which is type. They are similar, in that they both indicate how an argument keyword would be interpreted if used as a command name, but the output is different:

$ which ruby
/Users/jwworth/.rvm/rubies/ruby-2.1.0/bin/ruby
$ type ruby
ruby is /Users/jwworth/.rvm/rubies/ruby-2.1.0/bin/ruby

I prefer the type syntax, especially with multiple arguments:

$ type ruby rails bundler
ruby is /Users/jwworth/.rvm/rubies/ruby-2.1.0/bin/ruby
rails is /Users/jwworth/.rvm/gems/ruby-2.1.0/bin/rails
bundler is /Users/jwworth/.rvm/gems/ruby-2.1.0/bin/bundler

Type includes a handy -t flag, which tells you what type of thing the result is:

$ type -t type
builtin
$ type -t ruby
file

See help type (in Bash) for more information.

Full Backtrace in RSpec

Sometimes an RSpec error message can seem overwhelmingly verbose, other times frustratingly terse. Today I learned that this can be customized in Rails, with the following configuration:

# spec/spec_helper.rb
config.full_backtrace = false # or true?

Turn this on, and every failure will include a stack trace. Turn it off, and it won't. You can override a false setting at the command line, like so:

$ rspec spec/some/thing_spec.rb --backtrace 

Great for fast debugging.

See rspec --help for more information.

Write and Read Rails Attributes with Aliases

Lately I've been using a nice alias for writing record attributes in Rails, []=. Behold:

[1] pry(main)> d = Developer.new
=> #<Developer:0x007ff7130f8ef0
[2] pry(main)> d[:username] = 'isaacemard'
=> "isaacemard"
[3] pry(main)> d.username
=> "isaacemard"

That's all it takes. There's a getter variant, too:

[4] pry(main)> d[:username]
=> "isaacemard"

Here's how I used it today:

# app/models/developer.rb
before_create :generate_slug

def generate_slug
   self[:slug] ||= SecureRandom.hex(5)
end

To me this code reads a lot more nicely than write_attribute(attr_name, value). These aliases have been a part of Rails since at least 2012.

Source

h/t Mike Chau and Chris Erin

Test Your Nginx Configuration

Nginx misconfiguration can produce vague messages like these:

jake@myserver-2:~# sudo service nginx reload
 * Reloading nginx configuration nginx
   [fail]

Turn up the verbosity with this command:

jake@myserver-2:~# nginx -c /etc/nginx/nginx.conf -t

The -c flag indicates a certain configuration file will follow; the -t flag tells Nginx to test our configuration. This produces much more useful errors like this:

nginx: [emerg] unknown directive "erver_name" in /etc/nginx/sites-enabled/default:3
nginx: configuration file /etc/nginx/nginx.conf test failed

erver_name should be server_name— we have an actionable error message.

Psql Help

Psql includes a built-in help command that is amazing.

With no arguments, it returns all the help:

app_development=# \h
Available help:
  ABORT    ALTER TABLESPACE    CREATE FOREIGN TABLE
...

With a Postgres command as an argument, it returns a specific help:

app_development=# \h abort;
Command:     ABORT
Description: abort the current transaction
Syntax:
ABORT [ WORK | TRANSACTION ]

And with an asterisk, it prints the full description for all the help commands.

Plus we get this nicety:

Note: To simplify typing, commands that consists of several words do not have to be quoted. Thus it is fine to type \help alter table.

Write better SQL in your REPL today!

http://www.postgresql.org/docs/current/static/app-psql.html

h/t Jack Christensen

Tutorial Better

When I'm going through an online video tutorial, I have to write all of the code shown to really solidify the concepts. As a result I spend a lot of time pressing CMD + TAB to toggle between the browser video and my Vim session. This method is inefficient.

Helium to the rescue. Helium is a floating browser window for OS X, with some nice features like transparency. Position it on top of your console session, watch the video, and hack away in realtime.

Helium Screenshot

http://heliumfloats.com/

h/t Dorian Karter

Rails Server in Vim

With the help of Rails.vim, we can start a Rails server without leaving our Vim session.

This starts a server, with the standard optional arguments:

:Rserver {options}

Adding a ! will kill the pid found in 'tmp/pids/server.pid', and then invoke :Rserver. Powerful!

See :help Rserver with Rails.vim installed for more information.

h/t Paul Haddad

Navigate Github Faster

On any Github repo page, typing gc will load the 'Code' tab, gi will load the 'Issues' tab, and gp will load the 'Pull requests' tab.

Twitter Media and Characters

Today while debugging, we realized something surprising about Twitter— attaching media to a tweet counts as characters and reduces the overall amount of characters available.

Try adding any picture to a tweet. You'll see the available characters drop. We experienced a consistent drop of 24, from 140 to 116, although this seems to have varied at different points in Twitter's history.

This can produce subtle failures in an API call; two-dozen (or so) phantom characters are subtracted just by adding an image and may push any tweet over the limit. Turning up our logs helped expose this issue.

Interact with Rails via Runner

The rails runner feature of the Ruby on Rails command line interface is pretty awesome.

The documentation states:

runner runs Ruby code in the context of Rails non-interactively.

Use it like the ruby command to execute Ruby code in the context of your Rails environment. Take this file:

# rails_runner_in_action.rb
puts Developer.count # 5
puts Post.count # 40
puts Channel.count # 17

And run it with:

$ rails runner rails_runner_in_action.rb
5
40
17

It also runs Ruby code right in the terminal, so this works (rails r is an alias):

$ rails r "puts Developer.count"
5

http://guides.rubyonrails.org/command_line.html#rails-runner

Delete Remote Git Tags

Tagging releases with Git is a good idea. In case your tags get off track, here is how you delete a Git tag locally and on a remote:

$ git tag -d abc
$ git push origin :refs/tags/abc
To git@github.com:hashrocket/hr-til
 - [deleted]         abc

It gets trickier if you're using Semantic Versioning, which includes dots in the tag name. The above won't work for v16.0.0. This will:

$ git tag -d v16.0.0
$ git push origin :v16.0.0
To git@github.com:hashrocket/hr-til
 - [deleted]         v16.0.0

Git Log With Authors

In my never-ending quest to better summarize my work at the end of the day using computers, I discovered today the Git --author flag. It works like this:

$ glg --since=midnight --author=dev+jwworth+mikechau@hashrocket.com
* 4ba91a8 (HEAD, origin/checkout, checkout) Add guard for manual entry of employee discount
* 3a4e4c9 Seed a coupon and code and auto-apply in preview
* cb1adee Add discount
...

The alias glg is discussed here.

I use this when multiple developers or teams are committing throughout the day to the same repository, to disambiguate our work from others. Ready to paste into your billing software of choice.

Conveying Intent with RSpec subject

Today during a test refactor, I discovered RSpec's subject method. We used it a lot, because it helps convey the test's intent.

subject can be used as a convenience method, and to define the intent of a test. If you've ever seen a comment # This is what we are testing, subject would be an upgrade to that.

Here are three passing examples of this method in practice, from most to least verbose.

Explicit, with a named subject:

RSpec.describe Array, "with some elements, explicit named subject" do
  subject(:array) { [1, 2, 3] }
  it "should have the prescribed elements" do
    expect(array).to eq [1, 2, 3]
  end
end

Explicit, with no name:

RSpec.describe Array, "with some elements, explicit subject" do
  subject { [1, 2, 3] }
  it "should have the prescribed elements" do
    expect(subject).to eq [1, 2, 3]
  end
end

Implicit:

RSpec.describe Array, "with some elements, implicit subject" do
  it "should have the default elements" do
    expect(subject).to be_empty
  end
end

Substitute this for let on your described class. There are a ton of interesting uses and edges for this method, so dig into those docs.

h/t Mike Chau

Documentation

Enter the PHP REPL

Working in a language you've never worked in before can be challenging. We've been doing some PHP source-diving lately, and I find having a REPL very useful for decoding unfamiliar syntax.

If you have PHP installed, entering the REPL is easy; just type php -a. The flag stands for Run as interactive shell. I guess the -i flag was already taken.

HTML in Markdown

Today I learned that you can add raw HTML directly into a Markdown file.

This realization came when trying to include an image in a blog post. I started out by linking to the image with standard Markdown syntax:

![Image](https://s3.amazonaws.com/jake/image.png)

But later realized I wanted to include a responsive Bootstrap class on the image, which I did with raw HTML:

<img src="https://s3.amazonaws.com/jake/image.png" class="img-responsive" alt="Image">

It's pretty cool that you can do both— Markdown syntax gets processed into HTML, but raw HTML can be used as well.

Start Postgres.app from the Command Line

Today I was trying to restore a production Postgres dump on a remote machine, to test some migrations. I haven't granted myself Heroku production database access, hence the SSH into a machine with a Heroku user that has access.

I quickly hit a problem— this remote machine runs Postgres using Postgres.app. Without that program, I'm out of luck. No local Postgres server, no production database restore, no testing.

It turns out you can start Postgres.app from the command line. Find the executable and call it.

jake@remote-machine:$ /Applications/Postgres.app/Contents/MacOS/Postgres

Postgres.app online. I enjoy the image of a remote machine waking up somewhere on a Sunday with a big blue elephant, and 'Welcome to Postgres'.

Query Size of Postgres Array

Today I learned how to query the size of a Postgres array. There are (at least) two methods that work.

The first is array_length. This requires you to know the array dimension you seek; a useful filter, although most of the time this will probably be 1:

hr-til_development=# select title from posts
hr-til_development=# where array_length(slack_notified_at_likes_threshold, 1) = 1;
                   title
-------------------------------------------
 Because Javascript
 Percent Notation
 DIY Grids for Designing UI in Illustrator
(3 rows)

When the dimension is 1, a more terse solution is cardinality:

hr-til_development=# select title from posts
hr-til_development=# where cardinality(slack_notified_at_likes_threshold) = 1;
                   title
-------------------------------------------
 Because Javascript
 Percent Notation
 DIY Grids for Designing UI in Illustrator
(3 rows)

Documentation

Default to Empty Array in Postgres

Today I added an array of integers to a Postgres table, and like all such migrations, it will default to null for each new record.

This was a problem, because I wanted to use Rails 4's built-in Postgres array support to make decisions based on that data. Ruby array methods like include? will raise NoMethodError: undefined method 'include?' for nil:NilClass if that array is ever nil, which it is by default.

This led me to learn how to set the default value to an empty array using Postgres array literal syntax. I was then able to include a not null constraint as an added benefit:

# db/migrate/20160211043316_add_slack_notified.rb

def up
  execute <<-SQL
    alter table posts
      add column slack_notified integer[] not null default '{}';
  SQL
end

Variable Hoisting in Ruby

This afternoon my pair and I spent quite a while on a subtle bug. The culprit? Variable hoisting.

Take this file:

class Test
  def self.hoist
    require 'pry'; binding.pry;
    bar = 1
  end
end

Test.hoist

When we hit the PRY debugger, what will the value of bar be? I would have thought it would raise NameError, because bar has seemingly not yet been defined.

Wrong:

$ ruby test.rb

From: /test.rb @ line 4 Test.hoist:

    2: def self.hoist
    3:   require 'pry'; binding.pry;
 => 4:   bar = 1
    5: end

[1] pry(Test)> bar
=> nil

When Ruby parses a file, it 'hoists' each variable to the top of its scope, declaring and setting it to nil, even if that variable is never assigned by our code. So variables inside an if false conditional get hoisted and set to nil, as described in this blog post.

This is can be a real gotcha.

h/t Jack Christensen

Colorize MiniTest Output

I use MiniTest all the time for my hobby Ruby projects. I like its simple syntax and easy setup.

The test output can be a little sparse. Today I learned that it's easy to colorize the output of MiniTest, just like the defaults in more heavyweight test frameworks.

Add this to your Gemfile:

gem 'minitest-rg'

Then require the package in any test:

# test/my_test.rb

require 'minitest/rg'

Now we get a nice red, green, yellow colorized output.

minitest-rg

Checkout a Pull Request

Today I learned how to checkout and inspect a Git pull request locally.

Open the .git/config file in the root of the project directory. Locate the [remote "origin"] section, and add this line:

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Fetch the changes, and you should receive the pull request references:

From github.com:hashrocket/hr-til
 * [new ref]         refs/pull/1/head -> origin/pr/1
 * [new ref]         refs/pull/10/head -> origin/pr/10
 * [new ref]         refs/pull/11/head -> origin/pr/11
...

From here, you can checkout any pull request with git checkout pr/1, git checkout pr/10, etc.

Source: https://gist.github.com/piscisaureus/3342247

Ruby Text Objects

Today I discovered the amazing Ruby text objects feature of the plugin Vim-ruby.

Vim-ruby give us these four objects:

  • am ('a method')
  • im ('inner method')
  • aM ('a class')
  • iM ('inner class')

These can be composed with d, c, and v to build great editing tools like cim (change inner method) or vaM (select a class).

Split Strings with Trailing Nulls

Ruby's String .split accepts an optional number argument, and this lets us do some interesting things.

For instance, here is a naive full name splitter using such an argument:

> first_name, last_name = 'Benico del Toro'.split(' ', 2)
 => ["Benicio", "del Toro"]

It's naive because it doesn't work on names like 'Philip Seymour Hoffman', returning ["Philip", "Seymour Hoffman"].

Today I learned this argument can be negative. When it is, there is no limit to the number of fields returned, and trailing null fields are not suppressed:

> "Academy Award Winner....".split(".", 2)
 => ["Academy Award Winner", "..."]
> "Academy Award Winner....".split(".", -2)
 => ["Academy Award Winner", "", "", "", ""]

The actual value of the negative number seems to be irrelevant:

> "Academy Award Winner....".split(".", -1)
 => ["Academy Award Winner", "", "", "", ""]
> "Academy Award Winner....".split(".", -12)
 => ["Academy Award Winner", "", "", "", ""]

http://ruby-doc.org/core-2.3.0/String.html#method-i-split

Test Validation Errors with RSpec

We can use RSpec unit tests to confirm model validations, like this:

# app/models/developer.rb
validates :email, format: { with: /foo/ }

# spec/models/developer_spec.rb
developer.email = 'bar'
expect(developer).to_not be_valid

But there's a false positive here; expect returns true, but we can't be sure why it returned true. It may have been an invalid email, because the regex doesn't match bar, or it may be invalid for many other reasons, such as an incomplete fixture.

Another method I re-learned today is this:

# spec/models/developer_spec.rb
developer.email = 'bar'
expect(developer).to_not be_valid
expect(developer.errors.message[:email]).to eq ['is invalid']

The first expect triggers the validations; the second proves the right error was included. This makes a difference when flash messages or other code depend on your errors stack.

Ruby Regex Supports Interpolation

Today we built a Ruby regex that included an interpolated string. It looked like this:

# app/models/developer.rb
validates :email, format: { with: /\A.+@(#{ENV['permitted_domains']})\z/ }

This allows permitted_domains to be customized as an environmental variable:

# config/application.yml
permitted_domains: 'hashrocket.com|hshrckt.com'

The parens and pipe allow us to white-list multiple domains in a single environmental variable.

Reuse a Mac OS Installer

Once you've downloaded a Mac OS Installer, you know it takes a long time. Multiply that time and the half-hour installation by many workstations, and you have potentially days of work to upgrade them all.

We can slash that time by reusing the installer. ssh into a machine with the package, and ls /Applications/. We should see our directory, named Install\ OS\ X\ El\ Capitan.app/ (insert your OS version name). scp -r that directory to your local /Applications/, which should take a few minutes.

Back on your machine, find 'Install OS El Capitan' with the Finder, and follow the installation steps.

h/t Dillon Hafer

Load a File in the Leiningen REPL

Leiningen allows us to load a file right in the REPL, with (load-file name):

user=> (load-file "guess_the_number_with_feedback.clj")
#'user/guess-the-number

This returns the name of the last function defined, which is useful, because that's likely to be our main function or equivalent (which we would then call).

Here is the documentation, also from the REPL:

user=> (doc load-file)
-------------------------
clojure.core/load-file
([name])
  Sequentially read and evaluate the set of forms contained in the file.
nil

http://clojuredocs.org/clojure.core/load-file

Read Commented Notes

Want to resolve all those # TODO, # FIXME, and # OPTIMIZE comments in your Rails app? Good call, we don't want these getting too comfortable.

To demonstrate, push a note into a new file app/models/foo.rb:

$ echo '# TODO DRY this up!' >> app/models/foo.rb

Then run rake notes:

$ rake notes
app/models/foo.rb:
  * [1] [TODO] DRY this up!

rake -T | grep notes shows our options, including flags to filter results. We also get rake notes:custom, to find a custom note tag:

$ echo '# HACK woah.' >> app/models/foo.rb
$ rake notes:custom ANNOTATION=HACK
app/models/foo.rb:
  * [2] woah.

Show Clipboard in OS X

With Mac OS X, we can easily view the contents of our system clipboard.

From the command line, load something into the clipboard (I have used pbcopy):

$ echo "you found me" | pbcopy

Open up your Finder, and in the toolbar, click 'Edit > Show Clipboard'. A window will open with you found me on display.

Cat and Splat

Today I learned that cat supports splat (*).

This happened while I was trying to copy a handful of code examples to paste into a Gist, and I ran:

$ cat factor/examples/strings/* | pbcopy

This copied all the files in the strings/ directory into my clipboard, ready to paste into the Gist.

Get help with Pathogen

Today I found a great command in Pathogen.vim, :Helptags. This is a riff off :helptags {dir}, a Vim feature that builds helptags for directory {dir}.

:Helptags does the same for all the directories in your runtimepath, which defaults on Unix and Mac OS X to:

"$HOME/.vim,
$VIM/vimfiles,
$VIMRUNTIME,
$VIM/vimfiles/after,
$HOME/.vim/after"

The use case here is when you've just loaded a new plugin into your Vim bundle, you open up Vim, and :h {my_new_plugin} isn't 'helping' you out.

Generate a Rails Secret Key

Have you ever wondered about those secret keys found in config/secrets.yml of your Rails app? The comments generated in that file describe the keys as such:

'Your secret key is used for verifying the integrity of signed cookies.'

Great... but what if they become compromised? Or we need to change them? We can generate new ones.

Rails provides rake secret for just this purpose.

The source code is here. It's pretty simple; the code simply requires SecureRandom and spits out a string. If you want to be really clever, you can pipe the string directly into your Vim buffer for the config file, with :.! rake secret.

Check out rake -T | grep secret inside a Rails root directory for more information.

Show Model and Grep with Pry-rails

This week Josh Branchaud wrote about show-models in Pry-rails:

http://til.hashrocket.com/posts/62f61ee06f-show-rails-models-with-pry

This method has two nice variants. show-model User shows you that model, useful in a large database.

show-models also accepts --grep for searching:

[1] pry(main)> show-models --grep published
Post
  id: integer
  title: string
  published_at: datetime # 'published' is highlighted

Set a Default Scope

ActiveRecord provides default_scope, which you can use to control how records are returned. An example:

# app/model/chapter.rb
class Chapter < ActiveRecord::Base
  default_scope { order(:title) }
end

Now, instead of this (ordered by ID):

Chapter.all.pluck(:title).take(5)
=> ["BALINESE CAUSE",
"BUILDING RAT",
"TAIL",
"LILAC MERCURY",
"PUMP SQUARE"]

We get this:

Chapter.all.pluck(:title).take(5)
=> ["AFGHANISTAN COAT",
"ALCOHOL GONG",
"ANTARCTICA BULL",
"ASPARAGUS",
"BALINESE CAUSE"]

Beware, this decision can lead to inexplicable behavior down the road. Use with caution.

One use case I've heard is soft deletes. We might not want soft-deleted records appearing in .all:

# app/model/chapter.rb
class Chapter < ActiveRecord::Base
  default_scope { where('soft_deleted is false') }
end

h/t Brian Dunn

Change Inner Tag Block

Vim has excellent commands for changing the contents of parentheses (ci(), brackets (ci[), and squiggly braces (ci{) (as well as single quotes, double quotes, backticks, etc.). But what about tags?

Place your cursor anywhere inside the tags, type cit in Visual mode, and this:

<div>Begone</div>

Becomes:

<div></div>

d works too, but I prefer c because it puts you in Insert mode at the end of the opening tag, ready to type.

Check out :h v_it for more information.

h/t Josh Branchaud

Succeed, Precede, and Surround in Haml

Haml's design makes HTML and Ruby tricky to mix inline. But we have Haml helper methods to make it easier.

Here is succeed in action:

Developer at
  = succeed ', ' do
    = link_to "Hashrocket", "https://hashrocket.com/"

This becomes:

Developer at
<a href="https://hashrocket.com/">Hashrocket</a>,

Notice the comma at the end, outside of the a tag?

precede and surround work in a similar fashion, and do what we'd expect.

http://haml.info/docs/yardoc/file.REFERENCE.html#succeed

Increment and Decrement Numbers

Vim has commands built-in to increment and decrement numbers: CTRL-A and CTRL-X, respectively.

Combining this with a macro was a technique we tried today to build a large database migration. We ended up finding a more efficient solution, but it's still a very magical key combination.

Check out :help CTRL-A for more info.

h/t Josh Branchaud

Override Vim's Filetype

Vim's filetype auto-detection is great for effortless syntax highlighting, but what if a certain kind of file (i.e. Ruby) contains lots of another kind of code (i.e. SQL)? The Ruby code will be highlighted and readable, the SQL a large monochrome blob. Hard to read and reason about. We can do better!

Override the automatic assignment with:

:set ft=sql

This command with no assignment returns the current setting:

:set ft
=> filetype=lua

We can easily revert to the auto-detected extension as needed.

h/t Josh Branchaud

Postgres Arrays are One-Based

Today I was reminded that Postgres arrays are one-based. This realization came while using Ruby's times method (zero-based index) to generate SQL targeting a Postgres array (one-based index).

Take this table:

 name  |      pay_by_quarter
-------+---------------------------
 Bill  | {10000,10000,10000,10000}
 Carol | {20000,25000,25000,25000}
(2 rows)

To select the first-quarter pay for all employees, use index 1.

my_database=# select pay_by_quarter[1] from sal_emp;
 pay_by_quarter
----------------
          10000
          20000
(2 rows)

Using your first Ruby index value 0 to produce pay_by_quarter[0] returns a sad, empty column.

http://www.postgresql.org/docs/current/static/arrays.html

Grep Rails Routes

This week I found a treasure inside the Hashrocket Dotmatrix; behold:

# .zshrc
alias groutes='rake routes | grep $@'

This aliases rake routes | grep [foo], which I frequently use to search through big Rails routes files.

It looks like the Rails core team is responding to this pattern in Rails 5:

https://github.com/rails/rails/issues/18902

In the meantime, patch it yourself and reap the benefits.

h/t Dorian Karter & Jon Allured

Mark Test Pending With xit

Mark any RSpec test temporarily pending by changing it or specify to xit.

Take this test, from the 'Today I Learned' codebase:

# spec/models/channel_spec.rb

describe Channel do
  it 'should have a valid factory' do
    channel = FactoryGirl.build(:channel)
    expect(channel).to be_valid
  end
end

Change it to this:

# spec/models/channel_spec.rb

describe Channel do
  xit 'should have a valid factory' do
    channel = FactoryGirl.build(:channel)
    expect(channel).to be_valid
  end
end

Here's the test output:

$ rspec spec/models/channel_spec.rb:4
Run options: include {:locations=>{"./spec/models/channel_spec.rb"=>[4]}}

Channel
  should have a valid factory (PENDING: Temporarily skipped with xit)

...

Use this when refactoring code that breaks tests, to avoid deleting or commenting-out that hard-won test logic while you get back to green, test by test.

h/t Dorian Karter

Relish

Read a File Into Vim

In a Hashrocket blog post earlier this year I wrote about a command to read a file into your current Vim window:

:.! cat [filename]

A similar idea, from the command line:

$ cat [source_file] >> [target_file]

But with Vim there's always a better way:

:r[ead] [filename]

This command reads [filename] (defaulting to the current file) into in your window.

h/t Dorian Karter

Expect a Case-Insensitive Match

We had a testing issue this week when a button's text save changes! was rendering as SAVE CHANGES!, due to the CSS property text-transform: uppercase. How do you test that?

One technique is to use RSpec's match method, and include case insensitivity with i (explored earlier here):

> button_text = "foo"
=> "foo"
> expect(button_text).to match("FOO")
RSpec::Expectations::ExpectationNotMetError: expected "foo" to match "FOO"
# stuff
> expect(button_text).to match(/FOO/i)
=> true

We ultimately hard coded the expectation to match("FOO"), because allowing fOo and FoO seemed too permissive. But it remains an option.

Tmux Copy Mode

Last week we encountered a breaking change in our Tmux configuration, and briefly lost the ability to scroll with the mouse. It became an opportunity to re-learn Tmux's copy mode, and liberate ourselves from the mouse a little more.

Enter copy mode with <prefix> [. From here, you can navigate with standard Vim commands.

ctrl-u moves you a half-page up, perfect for wading through test failure backtraces.

Make directories with Vim Eunuch

Vim Eunuch has been my go-to Vim plugin this week.

The :Mkdir command is awesome. It's the mkdir you know and love, inside Vim. I find it useful when building a set of Rails views for a brand new controller. No more shelling out to make a directory, just to write my file.

:Mkdir! is even better because it adds the -p flag, creating all intermediate directories as well.

Move a File with Vim Eunuch

Among the many useful commands provided by Vim Eunuch is :Move.

:Move <new directory> renames a buffer and the file on disk simultaneously. It's the mv you know and love, right inside Vim.

Delete All Lines with Vim

I have a Vim pane I've been filling with throwaway code lately, and wanted to find the most efficient way to wipe it clean from inside Vim:

This is an option I've seen on message boards:

:1,$d

At seven keystrokes, it's pretty good. This is what I've been doing with five keystrokes:

ggdG

Starting on the first line (Vim's default) would make the gg redundant, bringing it down to three keystrokes. That might be the lower limit to how concise this can be, though I'd be glad to see someone do it with less.

Verifying Downloads with MD5

Today I downloaded Valgrind and wanted to verify the download's integrity. Valgrind provides an MD5 digest with each release that you can check against.

I used OpenSSL's md5 on OSX:

$ md5 valgrind-3.11.0.tar.bz2
MD5 (valgrind-3.11.0.tar.bz2) = 4ea62074da73ae82e0162d6550d3f129

This matches the digest on the Valgrind website, verifying the download. md5sum would be a comparable Linux program.

Inspect Your Previous Changes

Today I found a nice ActiveModel method for inspecting previous changes, previous_changes (SQL has been removed):

[1] pry(main)> k = Kit.first
=> #<Kit:0x007fb487cec988 id: 1, name: "Foo", ... >
[2] pry(main)> k.name = 'Bar'
=> "Bar"
[3] pry(main)> k.save
=> true
[4] pry(main)> k.previous_changes
=> {"name"=>["Foo", "Bar"], "updated_at"=>[Fri, 20 Nov 2015 17:57:50 UTC +00:00, Fri, 20 Nov 2015 18:00:51 UTC +00:00]}

If nothing was updated, the method returns an empty hash.

[1] pry(main)> k = Kit.first
=> #<Kit:0x007fb487dc47e8 id: 1, name: "Foo", ... >
[2] pry(main)> k.name = 'Foo'
=> "Foo"
[3] pry(main)> k.save
=> true
[4] pry(main)> k.previous_changes
=> {}

I can imagine many practical and potentially foolish applications for this information... planning to work it into a test at some point. ActiveModel::Dirty is full of interesting methods like this.

http://apidock.com/rails/ActiveModel/Dirty/previous_changes

Git Diff Numstat

Ever wanted to know how many lines have been added and/or removed by you current Git diff? There's a built-in command for just that:

$ git diff --numstat
28      1       README.md

My current changes add 28 lines and remove 1 line from the README.

Expecting A Selector and Its Content

In integration tests with Capybara, I find myself writing code like this a lot:

within 'h1' do
  expect(page).to have_content('Today I Learned')
end

Today I remembered that there is another way:

expect(page).to have_selector('h1', text: 'Today I Learned')

I prefer this because it captures the scope and the content in one line. RSpec integration tests in particular can get pretty long, and I think this is a good opportunity to keep them concise.

Testing Edit Forms

Today I found a way to assert that an edit form's inputs include a record's saved data. I think it strikes a good balance between broad and narrow scope.

# spec/features/user_edits_kit_spec.rb

within 'form' do
  expect(page).to have_selector("input[value='Default copy.']")
end

This asserts that some content is inside an input field in the form, rather than just anywhere on the page. You can narrow the scope as needed.

Know your HISTFILE

Today I learned that psql has a cool feature called the HISTFILE. It's a record of your commands in the REPL, named ~/.psql_history by default.

Building off Josh's post yesterday about ~/.psqlrc settings, add this there to get a unique log for each database:

\set HISTFILE ~/.psql_history-:DBNAME

Here's the tail of my TIL log:

$ tail ~./psql_history-hr-til_development
select * from developers limit 1;
select * from developers limit 2;
select * from developers limit 3;

This is just a text file; it can be edited. You could add a complex command, or meaningful reminder to yourself, and it will be available in psql when you traverse your history (↑ or CTRL-P).

After context in Grep

This is my standard grep through a git log:

$ git log | grep 'Extract oauth'
    Extract oauth response parsing

Cool; I found the commit I wanted. However, there is no context here-- I don't know the SHA, date, or committers.

Enter the -a flag, which stands for 'after context'. This flag will add some context to my results.

$ git log | grep 'Extract oauth' -a5 

commit 8e451afl4f292fb86ebbeca8baf5c9578355d3bf
Author: Liz Lemon and Jack Donaghy <dev+lizlemon+jackdonaghy@hashrocket.com>
Date:   Tue Apr 28 10:48:02 2015 -0500

    Extract oauth response parsing

commit a4d16le46ed4286732019c0024db07c85a179210
Author: Liz Lemon and Jack Donaghy <dev+lizlemon+jackdonaghy@hashrocket.com>
Date:   Tue Apr 28 10:17:54 2015 -0500

Now I can git show or git checkout that SHA, or anything else I need to do.

Delete a Line From Another Line

Today I was cleaning up a test with an extra empty line at the top of the file, away from my Vim cursor. I wanted to delete it... without moving the cursor.

It seems like Vim almost lets you do this, with :[range]d. But it leaves the cursor on the deleted line, which isn't very magical.

This is the hack we found:

:[range]d

Then:

''

'' returns the cursor to the last jump point.

h/t Josh Branchaud

Ruby's Kernel::abort

Today I used Ruby's Kernel::abort for the first time. It's one of those incredibly useful methods I can't believe I've never seen before.

Observe:

# abort.rb                                                                                                                                                    {1}
def no_message
  abort
end

def message
  abort('Process terminated')
end
$ irb
2.2.2 :001 > require './abort'
 => true
2.2.2 :002 > no_message
$ irb                                 {1}
2.2.2 :001 > require './abort'
 => true
2.2.2 :002 > message
Process terminated
$

Use it to bail from a script.

http://ruby-doc.org/core-2.1.2/Kernel.html#method-i-abort

Cleanup Postgres Databases

Today I learned that I have thirty-nine Postgres databases on my computer, after running this command inside psql:

\l ;

Each one is small, but I don't like to carrying around old data. I ended up dropping nine of them, with:

drop database foo_development;

For a lighter storage and cognitive load.

Finding Getters

After writing the other day about why you might not want to use simple getters, I decided that I wanted to eliminate all such methods from a project.

Here is the regex I wrote to isolate the pattern:

ag 'def (\w+);?\s+@\1;?\s+end'

The semicolon catches one-line getter methods as well as the more common three-line.

Accessor Performance Gap

This week I learned that attr_reader is more performant than a simple getter method.

Here’s a gist from five years ago where Aaron Patterson explains:

https://gist.github.com/pjb3/629716

I ran that same benchmarking script today on Ruby 2.2.3. The gap has narrowed, but still exists:

ruby-2.2.3
Rehearsal -----------------------------------------------
method        0.070000   0.000000   0.070000 (  0.074840)
attr_reader   0.050000   0.000000   0.050000 (  0.052603)
-------------------------------------- total: 0.120000sec

                  user     system      total        real
method        0.070000   0.000000   0.070000 (  0.072229)
attr_reader   0.050000   0.000000   0.050000 (  0.053374)

I like attr_reader because it’s a Ruby convention and is one line instead of three. Now, I also like its performance relative to a getter.

h/t Josh Davey

Accessors For All

Today I learned that accessors like attr_reader work in the private and protected visibilities.

class Test
  def initialize(getter, reader)
    @getter = getter
    @reader = reader
  end

  private

  def getter
    @getter
  end

  attr_reader :reader
end
2.2.3 :001 > t = Test.new('foo', 'bar')
 => #<Test:0x007f8f9b259bf8 @getter="foo", @reader="bar">
2.2.3 :002 > t.send(:getter)
 => "foo"
2.2.3 :003 > t.send(:reader)
 => "bar"

This can produce warnings in tests, discussed here:

https://bugs.ruby-lang.org/issues/10967

My current feeling is that these methods are a Ruby convention and should be used whenever appropriate, despite warnings in test.

Test Your Migrations

Today I discovered rake db:migrate:redo. This command rolls back a migration, and then runs the migration again. It's a convenience method for checking your work and iterating through complex migrations.

The Hashrocket Dotmatrix leverages this via the twiki method:

twiki () {
  rake db:migrate && rake db:migrate:redo && rake db:test:prepare
}

Migrate the database, then roll it back, then migrate it again, then rebuild the test database. If anything is wrong going up or coming down, this will catch it.

h/t Josh Branchaud

The Alpha Commit

I like to read commit logs.

Today I wanted to see the first commit on a project. Here's what I used:

git rev-list --max-parents=0 HEAD

Translation:

Show me the commits that led to* HEAD *in reverse chronological order; then limit those results to the commits with no parent.

Here's a small modification, to show the entire commit rather than the SHA alone:

git show $(git rev-list --max-parents=0 HEAD)

Rails restore_attributes

Today I found a useful method in ActiveRecord, restore_attributes.

This method restores attributes on a dirty model. Use it when you are hacking in the Rails console and want to quickly return to a clean slate.

Dirty the record:

pry> p = Post.first
=> #<Post:0x007f8462b09eb8
 id: 106,
 created_at: Sun, 09 Feb 2014 17:15:01 CST -06:00,
 url_slug: "hello-world">

pry> p.url_slug = 'foobar'
=> "foobar"

pry> p.created_at = Time.now
=> 2015-10-13 11:41:37 -0500

pry> p
=> #<Post:0x007f8462b09eb8
 id: 106,
 created_at: Tue, 13 Oct 2015 11:41:37 CDT -05:00,
 url_slug: "foobar">

And restore:

pry> p.restore_attributes
=> ["url_slug", "created_at"]

pry> p
=> #<Post:0x007f8462b09eb8
 id: 106,
 created_at: Sun, 09 Feb 2014 17:15:01 CST -06:00,
 url_slug: "hello-world">

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/dirty.rb#L191

Explore Buffers with BufExplorer

I'm a huge fan of Vim buffers. I try to have my buffer list roughly mirror the files I am currently holding in my brain.

The BufExplorer Vim plugin helps, and is included in the Hashrocket Dotmatrix. Today I learned to use the command \bs, which opens a colorful buffer list that you can navigate with Vim directions.

https://github.com/jlanzarotta/bufexplorer

Link to Headers in Github READMEs

Anytime you add a header to a markdown file, Github attaches an href with its downcased, punctuation-stripped name. 'JavaScript' receives a link to #javascript, for instance.

Spaces become dashes, so 'Command Line' becomes #command-line.

Leverage this by adding a table of contents to your README with links to the headers further down the document:

### Table of Contents

- [Cucumber](#cucumber)

This will link to a header containing 'Cucumber'.

h/t Josh Branchaud

Screen Flashing in OSX

I like a quiet computer. But I also like tab-completing commands in the terminal, which produces a necessary alert from time to time.

A solution I found today is to use OSX Accessibility features to add a screen flash on alerts, then disable the sounds.

System Preferences > Accessibility > Hearing menu, choose 'Audio' > Check 'Flash the screen when an alert occurs'

Rails destroy

The rails generate (g) command is useful for quickly creating the building blocks of a Rails app. Until you misspell or otherwise mess up a command:

% rails g model blurg_post
      invoke  active_record
      create    db/migrate/20151006162244_create_blurg_posts.rb
      create    app/models/blurg_post.rb
      invoke    rspec
      create      spec/models/blurg_post_spec.rb

'Blurg post'? I meant 'blog post'. Luckily, we can remove those auto-generated files as fast as we created them, with destroy (d).

% rails d model blurg_post
      invoke  active_record
      remove    db/migrate/20151006162244_create_blurg_posts.rb
      remove    app/models/blurg_post.rb
      invoke    rspec
      remove      spec/models/blurg_post_spec.rb

http://edgeguides.rubyonrails.org/command_line.html#rails-destroy

Watch That Program

Have you ever been working in the terminal and found yourself repeating the same command many times? Delegate that work to the computer.

watch comes with Linux and can be installed on OSX via homebrew. It executes a program periodically, defaulting to every two seconds.

We used it today while writing a database backup script. Instead of checking our dump directory every time a cron job executed, we ran watch ls, and watched the script succeed or fail with live updates.

man watch for more information.

Git Log Since

At the end of each day, I try to record what I did, to jog my memory during the next morning's standup. This helps:

git log --since="24 hours ago"

I SSH into my work machine and run this in my project's root directory. Combined with an alias from the Hashrocket Dotmatrix, glg (git log --graph --oneline --decorate --color --all), I get a terse summary of the day's work, ready to be pasted into your note-taking or project management tool of choice:

$ glg --since="24 hours ago"
* 7191b92 (HEAD, origin/master, origin/HEAD, master) Good changes
* 3f4d61e More good changes
* ecd9dcd Even more
...

Drop the --all if you only care about your current branch (and --decorate --color, they don't add value when only one branch is being examined).

glg --since=midnight is also useful.

Fetch your Environmental Variables

It's important to fetch Ruby environmental variables rather than directly referencing them.

This code depends on 'secret_key':

key = ENV['secret_key']

When 'secret_key' is not set, 'key' will be assigned nil, which is an object.

Later, a call to key.upcase will produce a NoMethodError, because Ruby doesn't know how to uppercase nil.

This is better:

key = ENV.fetch('secret_key')

Now, when 'secret_key' is not set, KeyError will be raised. The code fails fast.

fetch takes a second argument as a default, which means you can even prevent KeyError from ever happening, if you choose:

key = ENV.fetch('secret_key', 'some_default_numbers')

http://ruby-doc.org/core-2.2.3/ENV.html#method-c-fetch

Seeding Golang's rand

'Random' numbers in Go don't always seem random. This is because the rand package defaults to a seed of 1.

That's great if you need a bunch of random numbers at the start of your program. Not great if you expect a different outcome each time you run the program.

A solution is to seed rand with Unix time. Try it in the init() function:

package main

import (
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}
...

Build URLs with Window Location

Want to build URLs with JavaScript? Try thewindow.location object.

This came from a React.js project we're working on. It uses ES6 template string interpolation, which isn't necessary but definitely is nice:

`${window.location.protocol}//${window.location.host}/posts/${this.props.postID}/edit`

Which becomes:

"https://secret-project.com/posts/42/edit"

Postgres Unlogged

Using a Postgres table for caching? You might want to try making it unlogged.

unlogged tables are not written to the write-ahead log, which makes them much faster. This also means they are not crash-safe, and are truncated when a crash or unclean shutdown occurs. For caching purposes, that's likely to be an acceptable tradeoff.

Documentation

Go iota

Go has an interesting feature called iota. When declaring a list of constants, this keyword represents successive untyped integer constants.

const (
    foo = iota  // foo == 0
    bar = iota  // bar == 1
    baz = iota  // baz == 2
)

Anytime const is invoked, the counter resets.

const foo = iota  // foo == 0
const bar = iota  // bar == 0

This is a cool way to quickly define a list of integer constants, such as 'true' and 'false', for later use.

Vim Sort and Remove Duplicates

Today while rearranging a Ruby word array, I discovered this Vim command:

:sort u

This will sort all lines, or a given range, while also removing any duplicate lines.

Documentation

Ruby Regex Literal

Ruby has a nice percent string literal for regular expressions, %r. It's like // but allows your regex to contain backslashes without escaping them.

Check it out:

2.1.0 :001 > 'http://google.com'.gsub(/http:\/\/google.com/, 'fine')
 => "fine"
2.1.0 :002 > 'http://google.com'.gsub(%r{http://google.com}, 'better')
 => "better"

As the example implies, this is useful when matching URLs.

Documentation

Printing with lpr

Recently while trying to fix a printer I used lpr a bunch of times. It's not exactly new to me, but never fails to surprise people when I use it.

lpr submits files for printing to your default printer in OSX.

Print a file:

lpr README.md

Print the current file in your Vim session, with a cool job name:

:! lpr -T 'cool job name' %

Print two copies to a specific printer:

lpr -# 2 -P specific_printer README.md

This is an invaluable command-line trick.

Psql connect

Want to change database connections from inside psql? You can!

Psql, the REPL for Postgres, has a useful meta-command called \connect, or \c. This lets you establish a new connection to a Postgres server, while closing the current connection.

Here is the required format:

\c or \connect [ dbname [ username ] [ host ] [ port ] ] | conninfo

Only \c [my_database] is required; omitted parameters are taken from the previous connection.

Documentation

Open Files in Vim Splits

You can open multiple files with Vim in vertical or horizontal splits. To demonstrate, I'll create some test files.

$ touch a.txt b.txt c.txt d.txt e.txt

From the command line, vim -o *.txt will open these five files in vertical splits. vim -O *.txt will open them in horizontal splits. This is great for quickly comparing two files side-by-side.

Load vimrc inside Vim

While building a .vimrc configuration file, you can test the effect of your changes by loading them up while still in the Vim session:

:so %

This is shorthand for 'source the current file'. It will raise Not an editor command: <foo> if your syntax is incorrect, a useful side effect when quickly iterating through changes to your setup.

Ruby's __END__

I recently used Ruby's __END__ keyword in a client project.

__END__ denotes the end of regular source code in a Ruby file; nothing below it will be executed.

It's essentially a one-line block-commenting device, which is how we used it when trying to recreate a successful pattern borrowed from somewhere else in the project. Instead of toggling between files, we copied beneath __END__ the code we wanted to emulate, started building the new method, and cleaned up before committing.

One benefit of this technique is that any code below __END__ is available via the special filehandle DATA:

# foo.rb
puts DATA.map(&:upcase)

__END__
'foo'
'bar'
'baz'
$ ruby foo.rb
'FOO'
'BAR'
'BAZ'

Documentation

Sublime Text Highlights Heredocs

Sublime Text allows an awesome syntax highlighting trick. If you name a here document something generic, like HEREDOC, all the text within will be highlighted in one color, just like a Ruby string.

But if you name your here document RUBY, Sublime will override the normal highlighting and maintain Ruby-specific syntax highlighting within the here document. Same goes for SQL, JS, and probably more.

This is cool because it makes here documents that contain code a lot easier to write and debug.

Tailing with Less

Ready for some next-level log tailing?

Try opening your log file with the terminal pager Less and executing F. This is called 'scroll forward' and it works like tail -f from the command prompt, but you also get all the features (search, scroll, regex, etc.) of Less.

Array method

Ruby's Array(arg) method, from the Kernel class, is awesome. I like it because to me it's really clear what it does (type casting), and it tries both to_ary and to_a.

Also, it just looks cool.

2.1.0 :001 > Array(%w(some cool words))
 => ["some", "cool", "words"]
2.1.0 :002 > Array("word")
 => ["word"]
2.1.0 :003 > Array(nil)
 => []
2.1.0 :004 > Array(1..5)
 => [1, 2, 3, 4, 5]

Which Branches Have This Commit?

Imagine you have found an important commit in a complex git tree. Now you'd like to know which branches have this commit. Are the commit's changes on the branch we just deployed to staging?

--contains to the rescue:

$ git branch --contains <SHA>
* master
* staging
* feature/killer-feature

These three branches contain commit <SHA>.

View History of a File

Today we explored the history of a file with this command:

git log --follow -p -- file.txt

This displays every snapshotted change to 'file.txt' in your git history, including before and after file renames, in the highly readable --patch format. Learn from the past!

Source

Ruby usec

Two Time objects are almost never equal:

2.2.2 :001 > t = Time.now; t2 = Time.now
 => 2015-08-11 19:22:39 -0500
2.2.2 :002 > t == t2
 => false

This is true despite the fact that they were created in the same second of time, which we can verify by casting them to integers.

2.2.2 :003 > t.to_i
 => 1439338959
2.2.2 :004 > t2.to_i
 => 1439338959

The difference between these two times is in microseconds, which aren't displayed by default. Cast them as floats to see the difference.

2.2.2 :005 > t.to_f
 => 1439338959.099774
2.2.2 :006 > t2.to_f
 => 1439338959.099776

Another path to this information is Ruby's usec method, which returns just the microseconds.

2.2.2 :007 > t.usec
 => 99774
2.2.2 :008 > t2.usec
 => 99776

Documentation

Explicitly Set Table Name

ActiveRecord includes a table_name method that infers your database table name based on a class name. For an empty model called AlternativePost, here's what it comes up with:

[0] > AlternativePost.table_name
=> "alternative_posts"

If this isn't right, you're in trouble (Postgres example):

[1] > AlternativePost.new
PG::UndefinedTable: ERROR:  relation "alternative_posts" does not exist

Luckily, you can set the table name explicitly with the table_name= method.

class AlternativePost < ActiveRecord::Base
  self.table_name = 'posts'
end

Now Rails knows which database table to refer to:

[2] > AlternativePost.table_name
=> "posts"
[3] > AlternativePost.new
=> #<AlternativePost:0x007f8554dcbd98 id: nil, title: nil...

A practical application would be a model Post that corresponds to a table organized inside a Postgres schema admin.posts.

Change Owners and Groups Together

We can change the owner and group for a file or directory with this command:

$ sudo chown dev:dev test.txt

Now, the owner and group of 'test.txt' will be the 'dev' user and 'dev' group, respectively.

h/t Jack Christensen

source

SQL Truncate

Today during a smoke-test I watched a SQL-savvy colleague wipe a database table with the truncate syntax.

truncate users;

truncate is a feature of Postgres and is included in the SQL:2008 standard.

truncate includes a cascade option that further truncates all tables that have foreign-key references to any of the named tables, or any tables included by cascade itself. That sounds either useful or extremely destructive, depending on context.

This replaces my go-to for this type of cleanup, the Rails console:

User.delete_all

The benefits of truncate over delete_all are that you have more control and it's probably a little faster due to requiring one less layer of abstraction.

delete_all & truncate

RSpec let!

RSpec's let method comes in two varieties.

let can be used to define a memoized helper method.

let(:current_user) {  FactoryGirl.create :user }

But let is lazily-evaluated, meaning it isn't evaluated until the first time the method is invoked. The value returned will be cached across multiple calls in the same example.

let! forces the method to be evaluated before each example in a before hook.

let!(:current_user) {  FactoryGirl.create :user, active_range: (Time.now)...(Time.now + 1.second) }

You might use `let! when you need a method to be invoked before each example, or when measuring precise time-dependent behavior where lazy evaluation could produce inconsistent results.

Source

Reset Postgres User Password

Resetting a Postgres user's password with alter role is fine, but there is a better way! Try:

\password [ username ]

This changes the password of the specified user, defaulting to the current user. I like this because it prompts you for a password, encrypts it (security!), and sends it to the server as alter role. Your password will not appear as cleartext in the command history, server log, or anywhere else.

Source

h/t Jack Christensen

Ruby Partition Methods

One cool way to chop through a Ruby string is the partition String method. This uses regex to search for a match in a string. If it finds one, it returns what came before the match, the match, and what came after as elements in an array.

2.2.2 :001 > 'foo bar baz bat'.partition 'bar'
 => ["foo ", "bar", " baz bat"]

This is not to be confused with the partition Array method, which takes a block. Any elements that evaluate true are returned first, followed by the elements that evaluate false.

2.2.2 :002 > [1,2,3,4,5].partition(&:even?)
 => [[2, 4], [1, 3, 5]]

Postgres Contains/Contained By Array Operators

Today I learned about the Postgres 'contains' array operator (@>). This compares two arrays, returning true if the first array contains all of the elements of the second array.

myapp_development=# select array[1,2,3] @> array[1,3];
 ?column?
----------
 t
(1 row)

myapp_development=# select array[1,2,3] @> array[5,9];
 ?column?
----------
 f
(1 row)

It works in reverse via the 'is contained by' array operator (<@).

myapp_development=# select array[1,3] <@ array[1,2,3,4];
 ?column?
----------
 t
(1 row)

A practical example might be comparing two arrays, one of names and one of common nicknames associated with that name.

Vim Range Copy And Move

Today I used the Vim command :88t143 to copy a let block from one unit test to another. Vim has a few terse commands that work on whole lines like this. Here are two:

:[range]co[py] {address}        :co :copy
:[range]m[ove] {address}        :m :mo :move

:t is an alias for :copy, so the command I used copied line 88 and pasted it below line 143. It's all about saving those keystrokes!

h/t Josh Davey & Josh Branchaud

Comment with Commentary

Commenting out a range of code is easy with the plugin commentary.vim.

Simply highlight the range of code in visual mode and type gc.

Undo the action with u, or by repeating the same gc command on your range.

h/t Josh Branchaud

Cleanup Cucumber Steps

Code that is never executed is bad. Try this on your brownfield test suite:

$ cucumber --dry-run -f stepdefs

The stepdefs flag reports the location of each step, and also which steps aren't being used by any test. Delete those dusty old steps!

--dry-run skips running the actual steps, a significant time-saver.

Ruby Redo

Ruby has a keyword redo that you might see inside a block. It causes the unconditional re-execution of the block, with the same parameter bindings as the current execution.

Here it is, causing an endless loop:

n = 0
until n == 1 do
  puts n
  n += 1
  redo
end

redo does not evaluate the 'until' condition, so the likelihood of it causing an endless loop is high.

I'd love to see a practical application. It seems to me that redo would have to be inside a conditional, based on some information coming from outside the loop-- information we are certain will eventually be false.

That's a lot to ask; I would avoid redo in most cases.

Ruby Array Set Intersection

Ruby's Array class has a method & which returns a new array containing elements common to two arrays, excluding duplicates.

I used this on a project today to compare a random number (17) to a set of numbers with special meaning to the program.

2.2.2 :001 > (5..32).step(3).to_a & [17]
 => [17]
2.2.2 :002 > ((5..32).step(3).to_a & [17]).size > 0
 => true

The order is preserved from the original array:

2.2.2 :003 > [2,3,1] & [1,2,3]
 => [2, 3, 1]

h/t Chris Erin

Ruby Threequals

Ruby's == is pretty straightforward. From the Object class documentation:

Equality — At the Object level, == returns true only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.

Some examples from the String class:

irb > 'foo' == 'foo'
 => true
irb > 'foo' == :foo
 => false
irb > 'foo' == 'bar'
 => false

The triple equals, ===, sometimes called a ‘threequals’ or ‘case equality operator’, is different (again from the Object docs):

Case Equality – For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

The threequals compares the type of two arguments. One way to think about a === b is: 'does b belong in a box a’?

A few examples:

irb > String === 'foo'
 => true
irb > Array === %w(one two three)
 => true
irb > Range === (1..10)
 => true
irb > /car/ === 'carpool'
 => true

All of these evaluate false when the == operator is used.

Ruby's case statement operator uses the threequals for its control flow.

h/t Chris Erin

http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-case http://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and

Change Column Null

The not null constraint is a great way to ensure data integrity. If a Rails model validates_presence_of an attribute, that column should be not null in the database.

Rails has a special migration method for setting this constraint.

change_column_null :users, :mandatory_attribute, false

You could also use the change_column method. The reason change_column_null is a better choice is that change_column requires you to state the type of the column; change_column_null does not.

change_column(table_name, column_name, type, options)
change_column_null(table_name, column_name, null, default = nil)

Create with Timestamp

Today I learned how to interpolate a timestamp at the command line. Here are two examples:

For a file:

$ touch test_$(date +%s).md
$ ls
test_1435435401.md

For a git branch:

$ git checkout -b pull_request_$(date +%s)
Switched to a new branch 'pull_request_1435435344'

The timestamp represents seconds since the UNIX epoch.

Swapping Letters With Vim

Imagine you've typed 'recieve' instead of 'receive' in an RSpec test. This is will break things. I use this example because it's a typo I make frequently.

To swap the letters, move to the first letter ('i') and type xp. This will swap that letter with the next letter. It's Vim for 'cut what's under the cursor, then paste it after the cursor.'

There are more complex ways to do this; this is the simplest I know of.

h/t Matt Polito

jQuery Empty

Today I learned about the jQuery .empty() method.

.empty() removes all child nodes of the set of matched elements from the DOM. Consider it a delete button for whatever element you call it on.

.empty() is equivalent to .html('') but much faster.

h/t Cameron Daigle

Tmux Zoom

Tmux 1.8 introduced a great feature, zoom. Zoom expands the current pane to temporarily fill whole screen. It's helpful when you want to focus or read long lines of code.

The long way to this function is resize-pane -Z -t target-pane in the Tmux bar.

By default it is also mapped to prefix + z.

A cool alternative is to map Up and Down to toggle the zoom. That's how it works in the Hashrocket Dotmatrix:

# tmux.conf
unbind Up; bind Up resize-pane -Z; unbind Down; bind Down resize-pane -Z

h/t Chris Erin

JavaScript Casing

The ES5 spec defined two methods for changing the case of a string, .toUpperCase() and .toLowerCase(). They work just like Ruby's upcase and downcase.

'test'.toUpperCase()
=> "TEST"
'TEST'.toLowerCase()
=> "test"

There are two similar methods called .toLocaleUpperCase() and .toLocaleLowerCase() which are intended to yield the correct result based on the host environment's locale. I have not seen these methods in the wild but I'm curious if they are used.

Homebrew Info, Doctor, and Search

I learned a couple of Homebrew commands today. The first is brew info, which tells you about your Homebrew installation. Pass it a package name, and Homebrew will tell you about that package.

The next is brew doctor. This will give you an overview of your Homebrew environment, including unexpected files and symlinks, and whether there is a newer version of Homebrew available than the one you have.

The third is brew search. Pass this a package name and Homebrew will tell you all the versions that are available.

$ brew search phantomjs
homebrew/versions/phantomjs17      homebrew/versions/phantomjs192
homebrew/versions/phantomjs182     homebrew/versions/phantomjs198
Caskroom/cask/phantomjs

You can then brew install homebrew/versions/phantomjs182 to get the version you need.

RSpec Specify

There are more ways to create a test block with RSpec than it. One is specify, and you can use it to make your tests more readable. Consider this block:

describe 'doing everything' do

  it 'in space' do
    # actions
  end

The sentence 'it in space' is awkward. You can replace it with 'specify', which brings us very close to a grammatically correct sentence. This is Ruby after all; we try to make it readable.

describe 'doing everything' do

  specify 'in space' do
    # actions
  end

JavaScript Trim

The ES5 specification defined a new native method, trim(). It works just like Ruby's strip:

'   value   '.trim()
=> "value"

This is great for stripping extra whitespace from a user's input.

RSpec Profile

RSpec includes an easy way to measure test speed, the -p (profile) flag. It takes an argument [COUNT] representing the number of blocks to measure, defaulting to 10.

Here's some sample output:

Top 3 slowest examples (0.03332 seconds, 57.9% of total time):
  Developer should have a valid factory
    0.0199 seconds ./spec/models/developer_spec.rb:4
  Post should have a valid factory
    0.00816 seconds ./spec/models/post_spec.rb:4
  Post should require a body
    0.00525 seconds ./spec/models/post_spec.rb:16

View Vim Mappings

Somehow the Vim :map command eluded me until today. :map with no arguments lists you all your Vim mappings. If you have a lot of plugins, you have a lot of mappings.

Explore them and reap the benefits!

RSpec to HTML

With the RSpec -f (format) and -o (out) flags, and you can generate HTML representations of your test suite.

$ rspec spec/features/my_spec.rb -f html -o test_run.html
$ open test_run.html

Ready for a presentation, email, or archiving.

Code to HTML

The vim 'syntax.txt' plugin includes an awesome command called :TOhtml.

Highlight a range of code in Vim and run the command. Default range is the entire buffer.

You'll get an HTML document based on the code and its highlighting. Write the file and it is ready for a browser, a presentation, or anyplace else.

Assert No Selector

Capybara assertions can be very simple. Today I learned about the assert_no_selector and assert_selector methods.

Then 'assert_no_selector works' do
  assert_no_selector '.nonexistent-text'
end

Then 'assert_selector works' do
  assert_selector '.existent-text'
end

And here's the view that makes them pass:

# app/views/home/index.html.haml
.existent-text

No RSpec required!

Rails offset method

Rails has a method for skipping records in a query, 'offset'. It is available through the ActiveRecord::QueryMethods library.

User.offset(15) # generated SQL has "OFFSET 15"

The docs recommend using it with 'order'. I used the two methods today to return all blog posts, excluding the ten most recent:

Post.order('created_at desc').offset(10)

Rename Tmux Windows

When you create a window in tmux, it will be named 'zsh', or 'bash', or whatever your shell is. I think it's important that each tmux tab have an appropriate name. A tab running server should be called 'server'; a tab running sidekiq should be called 'sidekiq'.

You can rename your windows a bunch of ways. For the window you are in:

$ tmux rename-window newname

For another window in your session:

$ tmux rename-window -t otherwindow newname

Using the tmux bar:

prefix + rename-window newname

And my favorite, the tmux bar with a keyboard shortcut:

prefix + , newname

Bundle Open

Looking to source dive? This command opens the source directory for the provided gem.

bundle open GEM

Close All Windows

The Vim command :only, or :on, closes all windows except the one you are currently in.

Casting Created At

Four posts have been created for ’Today I Learned’ since yesterday. This code looks like it would return that count, but it doesn’t.

Post.where('created_at between ? and ?', Date.yesterday, Date.today).count              
   (0.8ms)  SELECT COUNT(*) FROM "posts" WHERE (created_at between '2015-06-09' and '2015-06-10)
=> 2

It returns 2; the two posts from yesterday but not the posts from today.

This is because Date.today is a Ruby Date object, which represents midnight on the given date, while created_at is a Rails ActiveSupport::TimeWithZone object, which includes time and zone details. Using Date.today as a comparator actually excludes any posts created after midnight today.

One solution is to cast created_at to a date:

Post.where('cast(created_at as date) between ? and ?', Date.yesterday, Date.today).count
   (1.1ms)  SELECT COUNT(*) FROM "posts" WHERE (cast(created_at as date) between '2015-06-09' and '2015-06-10')
=> 4

In the scope of this query, created_at loses its time information, so a post created today will return true when compared to Date.today. This is the Rails equivalent:

Post.last.created_at.to_date == Date.today
=> true

More Info

Conditional Callbacks

Rails has a method for triggering a callback conditionally: <column>_changed?. In the case of my current project, I want to trigger a Slack web hook only if a specific attribute, 'likes', has changed.

# app/models/post.rb
after_update :notify_slack, if: :likes_changed?

Of course, this logic could be moved into the callback method definition, but I like that it's stated upfront at the top of the class.

Clear your Git Stash

While looking at my git tree today, I noticed several stale git stashes hanging around. This command made them all go away:

git stash clear

Renaming Git Branches

Git branches can evolve into roles they weren't meant to fill. An example is an application with a branch called 'good-master', where all current development is happening, despite the existence of a stale branch called 'master'. We can fix this!

One solution is to merge 'master' into 'good-master'. But that can be tricky if you don't want a lot of the changes.

You can also rename the branches. In our case, 'good-master' is the true master branch, so 'master' should be deleted (or preserved, if you prefer).

$ git branch -m master master-old # rename master to master-old
$ git push origin :master # delete master at origin
$ git push origin master-old # create master-old at origin (or delete it)

$ git checkout good-master
$ git branch -m good-master master # rename good-master to master
$ git push origin :good-master # delete good-master
$ git push origin master # create new master

Next, change your default Github branch to the new master. Anyone new the project will find a more logical repo to work with. Existing developers can reset their local repo with:

$ git fetch origin
$ git reset --hard origin/master

To Sentence

Check out the Rails to_sentence method, which takes an array and returns a stringified sentence.

pry(main)> %w(one two three).to_sentence
=> "one, two, and three"

Really handy in the view layer. This method also accepts some interesting options like :words_connector and :locale.

Rebase with Execution

A powerful flag available during a git rebase is -x, or exec. It allows you to run a command, or multiple commands, on each commit in the rebase.

At Hashrocket we have an alias called reset-authors that sets your last commit's authors to the state of your current git config. Sometimes I need to do this on more than one commit in the past, and this is where -x shines:

git rebase -i HEAD^^^ -x git reset-authors

The opens a rebase TODO list with the following details:

pick c246420 Fix README
exec reset-authors
pick cc32abc Clarify routes
exec reset-authors
pick 27b6c62 Convert HAML to ERB
exec reset-authors

Save and close, and reset-authors will run on each commit in the list.

Rebase to Root Commit

You can rebase all the way back to your root (initial) commit with:

git rebase -i --root

Attempting this without the --root flag will raise this error:

fatal: Needed a single revision
invalid upstream

Classify and Constantize

Metaprogramming! Today I created a variable event that calls a serializer unique to the value of event. Along the way I learned about the Rails methods classify and constantize.

classify takes a plural table name and returns a class name.

> 'some_things'.classify
=> "SomeThing"

constantize tries to find a constant with the name specified in the argument string.

> "Module".constantize
=> Module

> "Nothing".constantize
NameError: uninitialized constant Nothing

Here's a sample of how I used these methods today (on the 'Today I Learned' app itself):

# app/models/post.rb
event = 'some_important_event'

# app/workers/event_notifier.rb
"#{event.classify}Serializer".constantize.new

This will new up an instance of SomeImportantEventSerializer, if such a class exists.

Invert a Hash

Ruby's Hash includes the method invert, which takes a hash and returns it with the keys and values reversed.

2.2.2 :001 > {blackhawks: 'chicago'}.invert 
 => {"chicago"=>:blackhawks}

Remove Belongs To Association

To remove a belongs_to association using the Rails migration DSL, use the remove_references method. This method is aliased to remove_reference and remove_belongs_to.

class RemoveTagReferences < ActiveRecord::Migration
  def change
    change_table :posts do |t|
      t.remove_references :tag
    end
  end
end

Replace ERB files with HAML

The gem htmltohaml provides an easy method to convert your ERB files into HAML files. It generates a new converted file with the .haml extension for each .erb file, leaving you with both copies.

Today I used this command to quickly remove about twenty of these redundant .erb files, after adding the .haml files.

$ find . -name \*.erb | xargs git rm

Find Or Create By With Block

The Rails find_or_create_by method is great for bringing something into existence only once. I like to use it for database seeds, so you get the basic objects you need to make your development site useable, but don't keep creating them over and over again.

One feature I recently learned is that this method takes a block.

User.find_or_create_by(first_name: 'Jake') do |user|
  user.last_name = 'Worth'
end

This lets you find the object, and if it doesn't exist, create it with whatever attributes you need.

Edit the Current File Always

The Vim command :e edits a file. Add a bang, :e!, to edit the current file 'always', discarding any changes to the current buffer.

This is useful if you rename a file with a new file extension (i.e. .txt to .rb). :e! reloads the file in Vim, picking up any customizations you have in your configuration files such as syntax highlighting.

Run Code if Current File is Calling File

This conditional tells Ruby to execute the code within if the current file is the file running the code.

# exec.rb
if __FILE__ == $0
  puts 'shown when exec.rb is run directly; not when required'
end

This works by comparing the current file (__FILE__) with the file that started the program ($0). If they aren't the same (exec.rb), the statement will not be printed.

Multipurpose Environmental Variables

I use HTTP Basic auth in non-production environments because it ships with Rails and is easy to implement. The first time I used it, I set it up like this:

# app/controllers/application_controller.rb
if ENV['http_basic_auth']
  http_basic_authenticate_with name: ENV['username'], password: ENV['password']
end

I used environmental variables so that no credentials were hard-coded, and so I could toggle it without deploying.

Today I learned you can also implement it like this:

# app/controllers/application_controller.rb
if creds = ENV['basic_auth_credentials']
  username, password = creds.split(':', 2)
  http_basic_authenticate_with name: username, password: password
end

This requires an environmental variable called basic_auth_credentials, set to <username>:<password>. I prefer this because it allows one variable to serve two purposes: it toggles the feature and also contains the information the feature needs to work.

It's a tradeoff; slightly less explicit, but simpler to set and unset (one variable versus three).

Puts Multiple Lines

Ruby's puts can take multiple arguments!

2.2.0 :002 > puts 'so', 'many', 'statements', 'to', 'puts'
so
many
statements
to
puts
 => nil

Truthy Strings

Ruby strings are truthy, and they evaluate to zero, unless they start with a number.

> 'nine to five'.to_i
 => 0
> '9 to 5'.to_i
 => 9

Prepare / Execute

You can store a SQL query with prepare.

db=# prepare posts_search as select title from posts limit 5;
PREPARE

Call the method with execute.

db=# execute posts_search;
               title
-----------------------------------
 Hello World!
 My First Pull Request: HAML
 My First Pull Request: Sinatra
 My First Pull Request: Capistrano
 My First Pull Request: SASS
(5 rows)

Deallocate the query with deallocate, and you can set it again.

db=# deallocate posts_search;
DEALLOCATE
db=# prepare posts_search as select title from posts limit 10;
PREPARE

Find and Replace Across Files

Vim can find and replace strings across files, just like other text editors. It's really (sort of) easy.

First, load all the files you want to change into the Vim buffer with a splatted directory.

:args path/to/files/*/*

Then, execute the substitution.

:argdo %s/old_string/new_string/ge | update

The e flag is important; it tells Vim not to issue an error if the search pattern fails. This will prevent No Match errors from breaking the chain.

MD5 File Signatures

The command md5 <file> generates a unique 32-digit hexadecimal number. This can serve as a signature for a file in its particular state, letting you know when it has changed.

Example usage:

$ touch test.txt
$ md5 test.txt
  MD5 (test.txt) = d41d8cd98f00b204e9800998ecf8427e
$ echo 'some content' > test.txt
$ md5 test.txt
  MD5 (test.txt) = eb9c2bf0eb63f3a7bc0ea37ef18aeba5

Directional Commands

You can move the cursor without arrow keys. Here is the keyboard equivalent for each.

  • Up ('previous'): CTRL + P
  • Down ('next'): CTRL + N
  • Left ('back'): CTRL + B
  • Right ('forward'): CTRL + F

Mapping caps lock to CTRL makes these combinations very accessible.

Current Value of a Setting

Check the value of any Vim setting by adding a ? to the end of its name.

# Validate spelling is turned off
:set spell?
=> nospell

# Validate incremental search is turned on
:set incsearch?
=> :incsearch

Date Input Tag

The HTML date input tag allows you to request dates in a web form.

<input type="date">

This tag is more semantic for date input than text, and provides a side benefit: Google Chrome will automatically display a calendar selector on the page.

Git snapshot

To save a snapshot of your current work in git, try this command:

git stash save "snapshot: $(date)" && git stash apply "stash@{0}"

This saves your current work in a timestamped stash, without removing it. In Hashrocket's dotmatrix this command is aliased to git snapshot.

Change column default

class AddDefaultFalseToDeveloperAdminFlag < ActiveRecord::Migration
  def change
    change_column_default :developers, :admin, false
  end
end

Modify attribute on set

In this example, we want to allow users to enter a twitter handle with or without an at-sign ('@'), just like Twitter, but save it without the at-sign. twitter_handle is already an attribute on the class.

class User < ActiveRecord::Base
  def twitter_handle=(handle)
    write_attribute(:twitter_handle, handle.to_s.gsub(/^@/, ''))
  end
end

Undo a git mistake

git reflog is a record of your commands in Git. With it, you can undo almost mistake you make with Git.

$ git reflog

4bd0090 HEAD@{0}: <bad change>
46bd839 HEAD@{1}: <bad change>
967e214 HEAD@{2}: <last good change>
46bd839 HEAD@{3}: <good change>
967e214 HEAD@{4}: <good change>

Now:

$ git reset --hard HEAD@{2}

Or:

$ git reset --hard 46bd839

Delete comments with Vim

:g/^\s*#/d will remove comment lines from a file with Vim.

Start rails server in production mode

rails s -e production

Upgrade Rubygems

To upgrade rubygems:

gem install rubygems-update
update_rubygems
gem update --system

less help

While in less (terminal pager program), h or H brings up a summary of commands.

Standard output to clipboard buffer

Adding | pbcopy to the end of any command will send the standard output to your clipboard.

ls -al | pbcopy inside a rails project directory allowed me to paste this:

Gemfile
Gemfile.lock
README.md
Rakefile
app
bin
config
config.ru
db
features
lib
log
public
script
spec
test
tmp
vendor

Buffer Wipe

If you use buffers to navigate Vim, and you open a file you didn't mean to edit or won't need later, wipe it from the buffer with :bw.

This will prevent that file from showing up in your buffers list. It will also delete any changes to the file; use with caution.

Parameters Filtering

Rails logs your server's activity, which is useful for development and debugging. However, often the server handles sensitive information that should not be logged.

A few examples are authentication credentials, personal data, and financial information.

To prevent Rails from logging such data, add this to your application configuration:

config.filter_parameters << :param_a, :param_b

When the named parameters are handled by the server, they will be logged as [FILTERED] instead of their actual value. Add this configuration by environment if you want to keep the parameters unfiltered in development.