Today I Learned

A Hashrocket project

Cascading function calls

Cascading function calls can be useful for building up properties on an object. We can simply return this at the end of each cascading function so that we always end up with the object when we're done.

Example - building a flash message after an ajax request in rails:

$.ajax({
        method: 'DELETE',
        url: url,
        contentType: 'application/json',
        error: function(status, data, jqxhr){
          var message = JSON.parse(status.responseText).error;
          var flash = new FlashBuilder('div');

          flash.text(message)
            .addClass('notification-error')
            .append('.flash-messages', '#some_container');
        }
      });
function FlashBuilder(el){
  this.element = $('<' + el + '>');

  this.text = function(text){
    this.element.text(text);
    return this;
  };

  this.addClass = function(klass){
    this.element.addClass(klass);
    return this;
  };

  this.append = function(target, container){
    if(container){
      $(container).find(target).append(this.element);
    } else {
      $(target).append(this.element);
    }

    return this;
  }
}

e.target vs this in delegated events

When attaching click handlers to elements, I used to think I could use e.target interchangeably with this. That is not true when we use event delegation.

Given the following JS:

    $('body').on('click', "[id^=delete_thing]", function(e){
      // do stuff
    });

And the following HTML:

<a href="javascript:void(0)" id="delete_thing_184">
      <img  src="/assets/ui/icon_delete.png">
      <strong> Delete Thing </strong>
</a>

When we click this link, we're actually clicking either the <strong> or the <img>. When the event e is passed to the callback, e.target is the element we actually clicked, and this is the element the click event bubbled up to, so use this instead of e.target.parent.

Responding with :stop allows call of `terminate`

A GenServer in Elixir has two lifecycle methods, init and terminate. init is called when the GenServer is started with GenServer.start_link.

What I learned today is that there is a terminate method in case there's any resources that need to be cleaned up when the GenServer is shut down. The terminate method is called when the :stop message is returned from either handle_cast or handle_call:

defmodule Cache do
  use GenServer

  #... a lot of other code

  def handle_cast({:something, 1}, state) do
    IO.puts "This executes first"
    {:stop, "This is my reason for stopping", state}
  end

  def terminate(reason, state)
    IO.puts "Then this executes"
  end
end

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

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:

Creating Indexes With Ecto

Using indexes in the right places within relational databases is a great way to speed up queries.

To add a basic index in an Ecto migration, use Ecto.Migration.index\2:

create index(:users, [:email])

Creating a composite index doesn't require jumping through any hoops; just put the relevant column names in the list:

create index(:posts, [:user_id, :title])

See h Ecto.Migration.index for more details.

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.

Open images in vim with iTerm πŸ–Ό

iTerm 3 has a built in shell script called imgcat for displaying images in the terminal. With one simple autocmd in my vim configuration I can open images*:

:autocmd BufEnter *.png,*.jpg,*gif exec "! ~/.iterm2/imgcat ".expand("%") | :bw

In my command I wipe the image buffer(:bw) because I don't want large images sitting around in buffers, but this is easy to change.

imgcat

*imgcat does not work with tmux

Use A Case Statement As A Cond Statement

Many languages come with a feature that usually takes the name cond statement. It is essentially another way of writing an if-elsif-else statement. The first conditional in the cond statement to evaluate to true will then have its block evaluated.

Ruby doesn't have a cond statement, but it does have a case statement. By using a case statement with no arguments, we get a cond statement. If we exclude arguments and then put arbitrary conditional statements after the when keywords, we get a construct that acts like a cond statement. Check out the following example:

some_string = "What"

case
when some_string.downcase == some_string
  puts "The string is all lowercase."
when some_string.upcase == some_string
  puts "The string is all uppercase."
else
  puts "The string is mixed case."
end

#=> The string is mixed case.

source

rel attribute for performance and security

The rel attribute on HTML links need to be set to noopener if you're using target=_blank in your links, otherwise the new tab contains a reference to the other tab's window object, and can redirect, manipulate dom, etc.

Read more and see a demo here: https://mathiasbynens.github.io/rel-noopener

There are also some performance benefits: https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/

List The Enqueued Jobs

Many Rails apps need to delegate work to jobs that can be performed at a later time. Both unit and integration testing can benefit from asserting about the jobs that get enqueued as part of certain methods and workflows. Rails provides a handy helper method for checking out the set of enqueued jobs at any given time.

The enqueued_jobs method will provide a store of all the currently enqueued jobs.

It provides a number of pieces of information about each job. One way to use the information is like so:

describe '#do_thing' do
  it 'enqueues a job to do a thing later' do
    Processor.do_thing(arg1, arg2)
    expect(enqueued_jobs.map { |job| job[:job] }).to match_array([
      LongProcessJob,
      SendEmailsJob
    ])
  end
end

To use this in your Rails project, just enable the adapter in your test configuration file:

Rails.application.config.active_job.queue_adapter = :test

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.

Requiring Keys For Structs

When defining a struct in Elixir, we may want to ensure that certain values are provided. We can require that certain keys are used in the creation of a struct with the @enforce_keys attribute. Here is an example of a Name struct.

defmodule Name do
  @enforce_keys [:first, :last]
  defstruct [:first, :middle, :last]
end

With this defined, we can create a struct that uses all of the keys.

> jack = %Name{first: "Jack", middle: "Francis", last: "Donaghy"}
%Name{first: "Jack", last: "Donaghy", middle: "Francis"}

We can also ignore :middle and just provide the required keys.

> liz = %Name{first: "Liz", last: "Lemon"}
%Name{first: "Liz", last: "Lemon", middle: nil}

We cannot, however, omit any of the keys specified in @enforce_keys. If we do omit any of them, Elixir will raise an error.

> tracy = %Name{first: "Tracy"}
** (ArgumentError) the following keys must also be given when building struct Name: [:last]
    expanding struct: Name.__struct__/1
    iex:6: (file)

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.

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

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.

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.