Today I Learned

A Hashrocket project

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.

Virtual Fields With Ecto Schema

If you'd like to include a particular key-value pair in an Ecto changeset, it needs to be included as a field in the schema. In the case of something akin to a password field, you want to be able to perform validations against it, but the password itself does not have a column in the database. In other words, you want to use the password in memory as part of the validation process but not save it to the database. To accomplish this, you need to specify that it is a virtual field.

schema "users" do
  field :username, :string
  field :password_digest, :string
  field :password, :string, virtual: true
end

With that schema, you can then validate the :password and transform it into the corresponding :password_digest field.

def registration_changeset(model, params) do
  model
  |> changeset(params)                  # do other standard validations
  |> cast(params, [:password])          # include :password in the changeset
  |> validate_length(:password, min: 8) # validations
  |> put_pass_hash()                    # transform into :password_digest
end

Generating UUIDs With pgcrypto

If you check out the docs for the uuid-ossp extension, you'll come across the following message.

The OSSP UUID library... is not well maintained, and is becoming increasingly difficult to port to newer platforms.

A little bit later, it says:

If you only need randomly-generated (version 4) UUIDs, consider using the gen_random_uuid() function from the pgcrypto module instead.

So, if we are using the UUID data type and only need to generate random UUIDs, we can rely on the pgcrypto extension. It comes with the gen_random_uuid() function which generates random v4 UUIDs.

> create extension "pgcrypto";
CREATE EXTENSION

> select gen_random_uuid();
           gen_random_uuid
--------------------------------------
 0a557c31-0632-4d3e-a349-e0adefb66a69

> select gen_random_uuid();
           gen_random_uuid
--------------------------------------
 83cdd678-8198-4d56-935d-d052f2e9db37

Close All Other Splits

If you have a couple other splits open, but you only want the window in focus, you may find yourself doing some finger gymnastics to navigate to those other split windows to close out of them.

There is an easier way.

The Ex command :only will close all other splits, excluding the window that is currently in focus.

See :h :only for more details.

Set persistent font in MacVim

Like many, I have MacVim installed through Homebrew Cask. When I first started using MacVim, I had to change the font to a powerline supported font so that my Airline looks spiffy.

To do that I went to Edit -> Font -> Show Fonts and selected a font.

Unfortunately this setting gets wiped out with each update of MacVim, and since it updates often, which is great, having to set the font over and over is not.

To have your font setting persisted in MacVim add this to your .gvimrc:

set guifont=Source\ Code\ Pro\ for\ Powerline:h24

You can set what ever font you like, just make sure to escape the spaces with a slash.

To get powerline (and Airline) patched fonts go here: https://github.com/powerline/fonts

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

Search Files Specific To A Language

The ack command makes it easy to narrow the set of searched files to those of a specific programming language. For instance, if you have a rails project and only want to search the ruby files, use the --ruby flag with your ack command.

$ ack --ruby Active

With the --ruby flag, I get a manageable number of results. Without it, not so much.

$ ack --ruby Active | wc -l
      26
$ ack Active | wc -l
    5253

See man ack for more details.

List Your Leader Vim Mappings

Mapping your Vim leader is a great way to customize Vim without clobbering keys that are already mapped. By default your Vim leader is \, but you can change it to another key - many people suggest , since it's so easy to type but I just use the default.

In any event, if you want to add a leader mapping how can you be sure that it's not already taken??

Easy, try this:

:map <leader>

Behold - a list of all mappings that involve your leader key.

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.

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

Exclude Whitespace Changes From GitHub Diffs

If you run a tidy ship and use plugins like vim-spacejam, then whitespace changes cluttering up your git diffs probably isn't much of an issue.

However, if you are working with other people or messier code bases, then you may not be so lucky. If there are a bunch of whitespace changes in a commit, then that is going to make the diff view of a commit on GitHub annoying, and perhaps hard, to read.

You can cut to the chase by excluding whitespace changes from GitHub's diff view by adding w=1 to the diff URL.

Check out this view of the diff and then this view of the diff that excludes whitespace.

source

Move to column in Vim

Jumping to a specific line in Vim is something I do all the time:

10G
# move to line number 10

In the last couple days I've wanted to jump to a specific character in a line. I did a quick Google search and found that you use pipe:

10|
# move to character number 10 in your current line

I wondered if there was anything else to know, so I hit the help file:

:he |

Which gives you:

To screen column [count] in the current line. exclusive motion. Ceci n'est pas une pipe.

And I was like, whaaa? A little more Googling and I found this:

https://en.wikipedia.org/wiki/The_Treachery_of_Images

And that there is a list of Vim help easter eggs:

http://vim.wikia.com/wiki/Best_Vim_Tips#Easter_eggs

It was like a TIL three-for-one!!

Simulating Various Connection Speeds In Chrome

I spend everyday building web apps from a machine that has a wired connection to the internet. Though I spend a lot of time loading various pages and experiencing the app like a user might, I end up having a pretty narrow perspective. What will this app be like for people on various qualities of mobile connections?

Chrome has a feature built in to its devtools that makes it easy to throttle your connection to simulate various speeds. Open up devtools with Cmd+Opt+J, navigate to the Network tab, and then open the throttling drop down.

From here we can select the connection speed we want to simulate. If we then reload the page, we will not only experience the page load at that speed, we will also see the numbers in that Network tab.

You have new mail.

Sometimes you forget to give that cron task somewhere to output its results... so it dumps them in your mail box... πŸ“¬πŸ˜£ all 30,000 times it failed to run.

You don't have to delete all those emails one by one πŸ˜‰

echo 'd *' | mail -N

d * means delete all mail. The -N means:

-N      Inhibit the initial display of message headers
        when reading mail or editing a mail folder.

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.

The case of meridian in Ruby's strftime

When formatting dates using strftime, you can include AM/PM with %p:

puts Time.now.strftime("%H:%M:%S %p")
# 20:40:52 PM

I didn't want PM capitalized, so I did this:

puts Time.now.strftime("%H:%M:%S %p").downcase
# 20:40:52 pm

But I found that you can also just use %P:

puts Time.now.strftime("%H:%M:%S %P")
# 20:40:52 pm

Yes that's right, when you want lowercase AM/PM, use uppercase P. When you want upppercase, use lower. It couldn't be more straightforward folks.

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.

Pipe | after | grep

The grep command may not work properly if you want to pipe another command after it, specially when you are tailing a file for example. Just call grep with --line-buffered

heroku logs -t | grep --line-buffered "heroku\[router\]" | awk '{print $11" "$5}'

This command outputs an easy-to-read performance log for each HTTP request:

service=266ms path="/api/posts"
service=142ms path="/api/users"

Pivoting a 2-dimensional list

In one of the exercism.io exercises, a grid is represented by a list of lists where each inner list represents a row.

The exercise then asks you to pivot the grid, that is, transform the list of lists so that each list represents a column.

From someone else's solution I learned that an easy way to conduct this transform is to use List.zip and Tuple.to_list.

grid = [[1,2,3, 4], [1,2,3, 4], [1, 2, 3, 4]]
List.zip(grid) 
|> Enum.map(&Tuple.to_list/1)
# [[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]

Tuple's to_list method is needed because List.zip returns an array of tuples.

Disable a pathogen plugin

Let's say I got this plugin that's just messing my editor up all day and I want to disable it. Because pathogen just looks at the plugins dir and loads whatever is there I can't just remove it from a manifest (or something similar).

There IS though a cool global vimscript var called g:pathogen_disabled that can be populated with all the vimscripts you'd like to disable.

It must be declared and populated before the call to pathogen#infect

let g:pathogen_disabled = []
call add(g:pathogen_disabled, 'vim-badplugin')
call pathogen#infect()

There ya go! Now vim-badplugin will not be included by pathogen!

PostgreSQL "RETURNING"

Today I learned that PostgreSQL INSERT/UPDATE/DELETE has a RETURNING clause that returns the computed values.

We can use it to get values that are generated by database such as sequences or defaults.

Check this out:

DROP TABLE IF EXISTS users;

CREATE TABLE users (
  id    SERIAL PRIMARY KEY,
  email VARCHAR NOT NULL UNIQUE
);

INSERT INTO users (email) VALUES ('user1@example.com');
-- INSERT 0 1

INSERT INTO users (email) VALUES ('user2@example.com') RETURNING *;
--  id |       email
-- ----+-------------------
--   2 | user2@example.com
-- (1 row)

h/t @joshuadavey

Map Caps Lock to Escape in macOS Sierra #seil

macOS Sierra was made available to the public yesterday and many of us early adopters rushed to install and test it out.

One of the things that broke and really affected my workflow was that Seil, the program I use to remap Caps Lock to ESC, no longer works. It's sister application Karabiner also stopped working.

Fortunately there's a solution available from the developer of Karabiner and Seil. It's a little more complicated than usual:

  1. Download and install Karabiner-Elements:

    https://github.com/tekezo/Karabiner-Elements

  2. Karabiner Elements will install a virtual keyboard driver, and you probably want to disable the default capslock behavior for the new virtual driver:

    disable capslock

  3. Use your favorite editor and edit the following file (create it if does not exist):

    vim ~/.karabiner.d/configuration/karabiner.json
    

    And add the following to it:

    {
        "profiles": [
            {
                "name": "Default profile",
                "selected": true,
                "simple_modifications": {
                    "caps_lock": "escape"
                }
            }
        ]
    }
    

That's it. Just make sure you have Karabiner Elements running.

Vim undo tree

Vim has an undo tree and there's two different ways to iterate with your changes.

One way to undo/redo changes is with: u and <Ctrl>r. This moves the current state based on the current branch in the tree.

The other way is using g- and g+. In this case it moves based on the timestamp of that change.

So here's an example to follow:

  1. add a line: added_line_1
  2. update this line: updated_line_1
  3. undo this change: u
  4. add another line: added_line_2

If you run through these steps your undo tree will be something like:

 o  [3] "added_line_2" <= "current_state"
 | *  [2] "updated_line_1"
 |/
 *  [1] "added_line_1"
 *  [0] "empty_file"

Now, if you undo with u will be in this state:

 *  [3] "added_line_2"
 | *  [2] "updated_line_1"
 |/
 o  [1] "added_line_1" <= "current_state"
 *  [0] "empty_file"

Otherwise if you undo with g- will be in this part of the tree:

 *  [3] "added_line_2"
 | o  [2] "updated_line_1" <= "current_state"
 |/
 *  [1] "added_line_1"
 *  [0] "empty_file"

You can check gundo vim plugin for tree visualization.

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

Aggregate Expressions with FILTER in Postgresql

Today I learned to use FILTER on aggregate expressions such as COUNT in postgresql.

See this example:

SELECT u.login,
       COUNT(1) FILTER (WHERE r.language ilike 'ruby') as ruby,
       COUNT(1) FILTER (WHERE r.language ilike 'javascript') as js,
       COUNT(1) FILTER (WHERE r.language ilike 'elixir') as elixir,
       COUNT(1) as all_langs
FROM users u
LEFT JOIN repositories r ON (u.id = r.user_id)
GROUP BY u.id;

-- login | ruby | js | elixir | all_langs
---------+------+----+--------+------------
-- bill  |    5 |  2 |      3 |         15
-- karen |    2 |  7 |      4 |         19
-- bob   |    9 |  1 |      2 |         23

h/t @joshuadavey

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