Today I Learned

A Hashrocket project

364 posts by joshbranchaud @jbrancha

Create A List Of Atoms

The ~w sigil makes it easy to create a word list -- a list of strings -- where each word is separated by a space.

> ~w(bulbasaur charmander squirtle)
["bulbasaur", "charmander", "squirtle"]

By appending an a onto that sigil construct, you are instructing Elixir that you would instead like a list of atoms.

> ~w(bulbasaur charmander squirtle)a
[:bulbasaur, :charmander, :squirtle]

source

Pretty Printing JSONB Rows in PostgreSQL

Who needs a document store when you can just use PostgreSQL's JSONB data type? Viewing rows of JSONB output can be challenging though because it defaults to printing them as a single line of text.

> select '{"what": "is this", "nested": {"items 1": "are the best", "items 2": [1, 2, 3]}}'::jsonb;
                                      jsonb
----------------------------------------------------------------------------------
 {"what": "is this", "nested": {"items 1": "are the best", "items 2": [1, 2, 3]}}
(1 row)

Fortunately, Postgres comes with a function for prettying up the format of the output of these rows -- jsonb_pretty

> select jsonb_pretty('{"what": "is this", "nested": {"items 1": "are the best", "items 2": [1, 2, 3]}}'::jsonb);
            jsonb_pretty
------------------------------------
 {                                 +
     "what": "is this",            +
     "nested": {                   +
         "items 1": "are the best",+
         "items 2": [              +
             1,                    +
             2,                    +
             3                     +
         ]                         +
     }                             +
 }
(1 row)

h/t Jack Christensen

Generating And Executing SQL

Rails' ActiveRecord can easily support 90% of the querying we do against the tables in our database. However, there is the occasional exceptional query that is more easily written in SQL -- perhaps that query cannot even be written with the ActiveRecord DSL. For these instances, we need a way to generate and execute SQL safely. The sanitize_sql_array method is invaluable for this.

First, let's get a connection and some variables that we can use downstream in our query.

> conn = ActiveRecord::Base.connection
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter ...>
> one, ten = 1, 10
=> [1, 10]

Now, we are ready to safely generate our SQL query as a string. We have to use send because it is not publicly available. Generally, this is frowned upon, but in my opinion it is worth breaking the private interface to ensure our SQL is sanitized.

> sql = ActiveRecord::Base.send(:sanitize_sql_array, ["select generate_series(?, ?);", one, ten])
=> "select generate_series(1, 10);"

Lastly, we can execute the query with our connection and inspect the results.

> result = conn.execute(sql)
   (0.4ms)  select generate_series(1, 10);
=> #<PG::Result:0x007facd93128a0 status=PGRES_TUPLES_OK ntuples=10 nfields=1 cmd_tuples=10>
> result.to_a
=> [{"generate_series"=>1},
 {"generate_series"=>2},
 {"generate_series"=>3},
 {"generate_series"=>4},
 {"generate_series"=>5},
 {"generate_series"=>6},
 {"generate_series"=>7},
 {"generate_series"=>8},
 {"generate_series"=>9},
 {"generate_series"=>10}]

Change To That New Directory

The $_ variable provided by bash is always set to the last argument of the previous command. One handy use of this is for changing directories into a newly created directory.

$ mkdir new_dir && cd $_

This command will leave you in your newly created directory, new_dir.

We can imagine using this bash variable in a number of similar scenarios as well. What if we are using some language specific command that creates a directory? Will it work when creating a new Phoenix or Rails project?

It sure will.

Give it a try with Phoenix:

mix phx.new my_app && cd $_

or with Rails:

rails new app && cd $_

source

Ins And Outs Of Pry

When executing commands during a Pry session, you'll see an incrementing number for each prompt as you enter each statement. These numbers can be used to look up the inputs and outputs of each statement executed during the session. The statements and their results are made available in the array-like _in_ and _out_ objects.

[1] pry(main)> :one
=> :one
[2] pry(main)> 1 + 1
=> 2
[3] pry(main)> ["t", "h", "r", "e", "e"].join
=> "three"
[4] pry(main)> _in_.to_a
=> [nil, ":one\n", "1 + 1\n", "[\"t\", \"h\", \"r\", \"e\", \"e\"].join\n"]
[5] pry(main)> _out_.to_a
=> [nil, :one, 2, "three", [nil, ":one\n", "1 + 1\n", "[\"t\", \"h\", \"r\", \"e\", \"e\"].join\n"]]
[6] pry(main)> _out_[2]
=> 2
[7] pry(main)> _in_[2]
=> "1 + 1\n"

source

Write A Query Result To File With Postgres

Generally when writing a query in psql a statement will be terminated with a semicolon. An alternative approach is to end it with a \g instead. This will also send the query to the Postgres server for execution.

select 1 \g

If a filename is included after the \g, then the result of the query will be written to that file instead of output to the psql session.

> select 1, 2, 3 \g query_result.txt

If we cat that file, we can see the query result.

Time: 4.293 ms
> \! cat query_result.txt
 ?column? | ?column? | ?column?
----------+----------+----------
        1 |        2 |        3
(1 row)

See man psql for more details.

What Is On The Runtime Path?

All of the plugins, syntax highlighting, language-specific indentation that extend the default behavior of Vim are on the runtime path. If something isn't on Vim's runtime path, then Vim won't know about and as a result will not load it at runtime.

How do we see what is on the runtime path?

The rtp option is the shorthand for runtimepath. Calling set on either of these will show us the list of runtime paths, or at least some of them.

:set rtp

This will generally be a truncated list if you have a lot of plugins. To be sure you are seeing all of them, use echo instead.

:echo &rtp

See :h rtp for more details.

h/t Chris Erin

Undo Some Command Line Editing

When using some of the fancy command line editing shortcuts, such as ctrl-u, you may end up erroneously changing or deleting part of the current command. Retyping it may be a pain or impossible if you've forgotten exactly what was changed. Fortunately, bash's command line editing has undo built in. Just hit ctrl-_ a couple times to get back to where you want to be.

h/t Chris Erin

source

Inspecting The Process Message Queue

A core tenant of Elixir is message passing between processes. So, if a process is sent a message, where does that message go? What happens if it gets sent many messages? The Process.info/2 function allows us to inspect the message queue.

First, let's send some messages (to ourself) and then keep an eye on the length of the message queue as we go.

> send self(), {:error, "this is bad"}
{:error, "this is bad"}
> Process.info(self(), :message_queue_len)
{:message_queue_len, 1}
> send self(), {:hello, "world"}
{:hello, "world"}
> Process.info(self(), :message_queue_len)
{:message_queue_len, 2}

Now, I am curious what those specific messages are. Let's ask Process.info/2 for the messages that are in the message queue.

> Process.info(self(), :messages)
{:messages, [error: "this is bad", hello: "world"]}

There are a lot of other things that Process.info/2 can tell us about a process. See the Erlang docs for process_info for more details.

Cherry Pick A Range Of Commits

Git's cherry-pick command allows you to specify a range of commits to be cherry picked onto the current branch. This can be done with the A..B style syntax -- where A is the older end of the range.

Consider a scenario with the following chain of commits: A - B - C - D.

$ git cherry-pick B..D

This will cherry pick commits C and D onto HEAD. This is because the lower-bound is exclusive. If you'd like to include B as well. Try the following:

$ git cherry-pick B^..D

See man git-cherry-pick for more details.

Hiding The tmux Status Bar

The tmux status bar is a great place to show information about your tmux session as well as things like the time and date. Sometimes you just want to hide it though. This command will help.

:set -g status off

Hit enter and it is gone. If you want to show the status bar again, simply turn it back on.

:set -g status on

source

Listing Files In IEx

When you start an IEx session, you do so in the context of some directory -- the current working directory. This context can be important if you need to do something like import a file. In fact, you may want to know what files are available in the current working directory.

You can list them all out within IEx using ls/0.

iex(1)> ls()
           .git     .gitignore      README.md         _build         assets         config
           deps            lib        mix.exs       mix.lock           priv           test
            tmp

You can also list the contents of some other specific directory by naming it when invoking ls/1.

See h() within IEx for more details.

Case-Insensitive Search With Ack

Use the -i flag to perform a case-insensitive search with ack.

$ ack -i easter

ack/ack-bar.md
3:The [`ack`](https://beyondgrep.com/) utility has a fun Easter egg that dumps

postgres/configure-the-timezone.md
18:Eastern time.

If you are a Vim user, you may be familiar with smart-case. The --smart-case option is a related Ack feature worth checking out.

See man ack for more details.

Update The URL Of A Remote

I just changed the name of a Github repository. One of the implications of this is that the remote URL that my local git repository has on record is now out of date. I need to update it.

If I use git-remote with the -v flag. I can see what remotes I currently have.

$ git remote -v
origin  git@github.com:jbranchaud/pokemon.git (fetch)
origin  git@github.com:jbranchaud/pokemon.git (push)

Now, to update the URL for that remote, I can use git remote set-url specifying the name of the remote and the updated URL.

$ git remote set-url origin git@github.com:jbranchaud/pokemon_deluxe.git

If I check again, I can see it has been updated accordingly.

$ git remote -v
origin  git@github.com:jbranchaud/pokemon_deluxe.git (fetch)
origin  git@github.com:jbranchaud/pokemon_deluxe.git (push)

Defining Multiple Clauses In An Anonymous Function

Anonymous functions often take the approach of doing a single thing with the inputs, regardless of their shape or values. There is no need to limit ourselves though. The same pattern matching that we use all over our Elixir programs can be utilized to define multiple clauses in an anonymous function as well.

Consider the following example:

iex> my_function = fn
  {:ok, x} -> "Everything is ok: #{x}"
  {:error, x} -> "There was an error: #{x}"
end
#Function<6.52032458/1 in :erl_eval.expr/5>

We can then invoke our anonymous function using the bound variable to see what results we get with different kinds of inputs.

iex> my_function.({:ok, 123})
"Everything is ok: 123"
iex> my_function.({:error, "be warned"})
"There was an error: be warned"

source

Remove The Default Value On A Column

You have a column on one of your database tables with a default value. You'd like to remove the default value. Removing the default is the same as setting it to nil. You can do this with the ActiveRecord DSL using the change_column_default method.

def change
  change_column_default :users, :age, nil
end

See the docs for more details.

Chaining Multiple RSpec Change Matchers

It can be handy to use RSpec's change matchers to determine if some method or process creates a new record.

expect{ Registration.create(attrs) }.to change{ User.count }.by(1)

But what if we are testing a method that creates a couple different records in the system?

RSpec allows us to chain together change matchers with and. Consider this additional contrived example.

expect {
  Project.generate(attrs)
}.to change{ Project.count }.by(1).and \
     change{ User.count }.by(1)

In addition to keeping our tests tight and concise, this approach gives some pretty nice output on failure.

If we were just beginning our implementation with a failing test, we'd see a multi-part failure like the following.

Failure/Error:
  expect {
    Project.generate(attrs)
  }.to change{ Project.count }.by(1).and \
       change{ User.count }.by(1)

     expected result to have changed by 1, but was changed by 0

  ...and:

     expected result to have changed by 1, but was changed by 0

List Available File Types For Ack

The ack utility allows you to filter the searched files based on file type. If you'd like to know all of the file types available, you can use the --help=types flag. This will include file types you've specified in your .ackrc file.

Here is a sample of some of the output.

$ ack --help=types
    ...
    --[no]css          .css .less .scss
    --[no]dart         .dart
    --[no]delphi       .pas .int .dfm .nfm .dof .dpk .dproj .groupproj .bdsgroup .bdsproj
    --[no]elisp        .el
    --[no]elixir       .ex .exs
    --[no]erlang       .erl .hrl
    --[no]fortran      .f .f77 .f90 .f95 .f03 .for .ftn .fpp
    --[no]go           .go
    --[no]groovy       .groovy .gtmpl .gpp .grunit .gradle
    --[no]haskell      .hs .lhs
    --[no]hh           .h
    --[no]html         .html .mustache .handlebars .tmpl
    --[no]jade         .jade
    --[no]java         .java .properties
    --[no]js           .js
    ...

See man ack for more details.

ack --bar

The ack utility has a fun Easter egg that dumps a Star Wars meme to the command line. Give it a try.

$ ack --bar

See man ack for more details.

Remove One List From Another

The --/2 operator allows you to subtract two lists, that is, remove all elements in the right list from the left list. Each occurrence of an element is removed if there is a corresponding element. If there is no corresponding element, it is ignored.

Here are some examples.

> [1, 2, 3] -- [2, 4]
[1, 3]
> [:a, :b, :c, :a, :d, :a] -- [:a, :a]
[:b, :c, :d, :a]

This kind of list operation is not particularly efficient, so for large lists it can be quite slow. The following example took several minutes to run.

> Enum.into(1..1000000, []) -- Enum.into(2..1000000, [])
[1]

To achieve a true set difference, you'll note that the docs for this operator recommend checking out MapSet.difference/2.

See h Kernel.-- for more details.

Referencing Values In IEx's History

Each time we execute a statement in an iex session, the counter is incremented. These numbers are references to the history of the session. We can use these references to refer to previously executed values using v/1. This is particularly handy for multi-line statements or when we forget to bind to the result of some function.

Consider the following iex session:

iex(1)> :one
:one
iex(2)> 1 + 1
2
iex(3)> "three" |> String.to_atom()
:three

If we execute v() on its own, it is the same as v(-1) in that it will give us the latest value in the history.

iex(4)> v()
:three

Providing any positive number will refer to the references we see next to each statement.

iex(5)> v(1)
:one

Negative numbers, as we saw with v(-1), will count backwards in the history from where we are.

iex(6)> v(-4)
2

See h v for more details.

Creating A PID

Often times, when invoking a function that spawns a process, the PID of the spawned process is returned and we bind to it. That PID is a reference to some BEAM process in our system.

We can create our own references using the pid/3 function.

Let's assume we have the following processes, among others, in our system at the moment.

> Process.list |> Enum.reverse |> Enum.take(3)
[#PID<0.284.0>, #PID<0.283.0>, #PID<0.282.0>]

We can create a reference to any of them using the three number parts that they are made up of.

> pid(0, 284, 0)
#PID<0.284.0>

See, it's alive.

> pid(0, 284, 0) |> Process.alive?
true

What if we make up a PID that doesn't actually reference any process?

> pid(0, 333, 0) |> Process.alive?
false

Note: there is also a pid/1 version of the function. See h pid for more details.

Specifying The Phoenix Server Port

Running mix phx.server for a Phoenix project with the default settings will attach the server to port 4000.

If you'd like to use a different port in development, you can change it in config/dev.exs.

config :my_app, MyApp.Web.Endpoint,
  http: [port: 4444],
  ...

Alternatively, you can allow it to be configurable from the command line with an environment variable and a fallback port.

config :my_app, MyApp.Web.Endpoint,
  http: [port: System.get_env("PORT") || 4000],
  ...

Running

$ PORT=4444 mix phx.server

will launch the server on port 4444.

Prepare, Execute, and Deallocate Statements

In PostgreSQL, you can prepare a named statement to be executed later using prepare.

> prepare column_names (text) as
    select column_name from information_schema.columns where table_name = $1;
PREPARE

These statements are kept around for the duration of the session. To see the available statements, check out the pg_prepared_statements view.

> select * from pg_prepared_statements;
     name     |                                  statement                                  |         prepare_time          | parameter_types | from_sql
--------------+-----------------------------------------------------------------------------+-------------------------------+-----------------+----------
 column_names | prepare column_names (text) as                                             +| 2017-03-10 15:01:09.154528-06 | {text}          | t
              |   select column_name from information_schema.columns where table_name = $1; |                               |                 |

To run a prepared statement, use execute with the name of the statement and any arguments.

> execute column_names('users');
   column_name
-----------------
 id
 email
 password_digest
 created_at
 updated_at
 first_name
 last_name

You can also delete a statement with deallocate if you'd like.

> deallocate column_names;
DEALLOCATE

Get The pid Of The Session

Your current Vim session is a process running on your machine. That means that this session is tied to a particular process id, pid.

Want to know what the pid is?

:echo getpid()

This will echo the pid of your current Vim session.

See :h getpid() for more details.

Grep For A Pattern On Another Branch

Git has a built-in grep command that works essentially the same as the standard grep command that unix users are used to. The benefit of git-grep is that it is tightly integrated with Git. You can search for occurrences of a pattern on another branch. For example, if you have a feature branch, my-feature, on which you'd like to search for occurrences of user.last_name, then your command would look like this:

$ git grep 'user\.last_name' my-feature

If there are matching results, they follow this format:

my-feature:app/views/users/show.html.erb:  <%= user.last_name %>
...

This formatting is handy because you can easily copy the branch and file directive for use with git-show.

See man git-grep for more details.

Viewing A File On Another Branch

Sometimes you want to view a file on another branch (without switching branches). That is, you want to view the version of that file as it exists on that branch. git show can help. If your branch is named my_feature and the file you want to see is app/models/users.rb, then your command should look like this:

$ git show my_feature:app/models/users.rb

You can even tab-complete the filename as you type it out.

See man git-show for more details.

source

Check The Installed Version Of Phoenix

Check what the installed version of Phoenix is with the -v flag.

$ mix phoenix.new -v
Phoenix v1.2.0

source

Default netrw To Tree Liststyle

The built-in netrw plugin is a great way to browse files and directories within a Vim session. netrw supports four ways of displaying files and directories. That is, there are four liststyles. You can toggle through these by hitting i.

I prefer the tree liststyle, which is not the default. I can set the tree liststyle as the default by adding the following line to my .vimrc file.

let g:netrw_liststyle = 3

Now, every time I visit or revisit a netrw window, I'll see everything nicely displayed as a tree.

Between Symmetric in PostgreSQL

PostgreSQL's between construct allows you to make a comparison between two values (numbers, timestamps, etc.).

> select * from generate_series(1,10) as numbers(a)
    where numbers.a between 3 and 6;
 a
---
 3
 4
 5
 6

If you supply an empty range by using the larger of the two values first, an empty set will result.

> select * from generate_series(1,10) as numbers(a)
    where numbers.a between 6 and 3;
 a
---

Tacking symmetric onto the between construct is one way to avoid this issue.

> select * from generate_series(1,10) as numbers(a)
    where numbers.a between symmetric 6 and 3;
 a
---
 3
 4
 5
 6

BETWEEN SYMMETRIC is the same as BETWEEN except there is no requirement that the argument to the left of AND be less than or equal to the argument on the right. If it is not, those two arguments are automatically swapped, so that a nonempty range is always implied.

What Changed?

If you want to know what has changed at each commit in your Git history, then just ask git whatchanged.

$ git whatchanged

commit ddc929c03f5d629af6e725b690f1a4d2804bc2e5
Author: jbranchaud <jbranchaud@gmail.com>
Date:   Sun Feb 12 14:04:12 2017 -0600

    Add the source to the latest til

:100644 100644 f6e7638... 2b192e1... M  elixir/compute-md5-digest-of-a-string.md

commit 65ecb9f01876bb1a7c2530c0df888f45f5a11cbb
Author: jbranchaud <jbranchaud@gmail.com>
Date:   Sat Feb 11 18:34:25 2017 -0600

    Add Compute md5 Digest Of A String as an Elixir til

:100644 100644 5af3ca2... 7e4794f... M  README.md
:000000 100644 0000000... f6e7638... A  elixir/compute-md5-digest-of-a-string.md

...

This is an old command that is mostly equivalent to git-log. In fact, the man page for git-whatchanged says:

New users are encouraged to use git-log(1) instead.

The difference is that git-whatchanged shows you the changed files in their raw format which can be useful if you know what you are looking for.

See man git-whatchanged for more details.

Compute md5 Hash Of A String

To compute the md5 digest of a string, we can use Erlang's top-level md5 function.

> :erlang.md5("#myelixirstatus")
<<145, 148, 139, 99, 194, 176, 105, 18, 242, 246, 37, 69, 142, 69, 226, 199>>

This, however, gives us the result in the raw binary representation. We would like it in a base 16 encoding, as md5 digests tend to be.

We can wrap (or pipe) this with Base.encode16 to get the result we are looking for.

> Base.encode16(:erlang.md5("#myelixirstatus"), case: :lower)
"91948b63c2b06912f2f625458e45e2c7"

source

Counting Records With Ecto

Sometimes you want to know how many records there are in a table. Ecto gives us a couple ways to approach this.

We can use the count\1 function that the Ecto query API provides.

> Repo.one(from p in "people", select: count(p.id))

16:09:52.759 [debug] QUERY OK source="people" db=1.6ms
SELECT count(p0."id") FROM "people" AS p0 []
168

Alternatively, we can use the fragment/1 function to use PostgreSQL's count function.

> Repo.one(from p in "people", select: fragment("count(*)"))

16:11:19.818 [debug] QUERY OK source="people" db=1.5ms
SELECT count(*) FROM "people" AS p0 []
168

Lastly, Ecto.Repo has the aggregate/4 function which provides a :count option.

> Repo.aggregate(from(p in "people"), :count, :id)

16:11:23.786 [debug] QUERY OK source="people" db=1.7ms
SELECT count(p0."id") FROM "people" AS p0 []
168

Unique Indexes With Ecto

You can create a unique index in a migration for one or more columns using the unique_index/3 function.

For example, if you are creating a join table for followers and want to ensure that duplicate follower entries are prevented, you may want to include a unique index like so:

create table(:followers) do
  add :followed_user, references(:users), null: false
  add :following_user, references(:users), null: false
end

create unique_index(:followers, [:followed_user, :following_user])

Keep in mind that unique_index/3 is a shorthand for index/3 when you set unique: true.

Rerun Only Failures With RSpec

After running a big test suite, I may have a bunch of output on the screen including the results of a couple test failures. I like to bring the context of the test failures front and center and make sure they are consistent test failures (not flickering failures). Instead of copying and pasting each failure, I can rerun rspec in a way that executes only the test cases that failed.

$ rspec --only-failures

This feature requires that you set a file for RSpec to persist some state between runs. Do this in the spec/spec_helper.rb file. For example:

RSpec.configure do |config|
  config.example_status_persistence_file_path = "spec/examples.txt"
end

See more details here.

h/t Brian Dunn

Polymorphic Path Helpers

Underlying many of the path helpers that we use day to day when building out the views in our Rails apps are a set of methods in the ActionDispatch::Routing::PolymorphicRoutes module.

The #polymorphic_path method given an instance of a model will produce the relevant show path.

> app.polymorphic_path(Article.first)
  Article Load (0.5ms)  SELECT  "articles".* FROM "articles"  ORDER BY "articles"."id" ASC LIMIT 1
=> "/articles/2"

Given just the model's constant, it will produce the index path.

> app.polymorphic_path(Article)
=> "/articles"

Additionally, there are variants with edit_ and new_ prefixed for generating the edit and new paths respectively.

> app.edit_polymorphic_path(Article.first)
  Article Load (0.6ms)  SELECT  "articles".* FROM "articles"  ORDER BY "articles"."id" ASC LIMIT 1
=> "/articles/2/edit"
> app.new_polymorphic_path(Article)
=> "/articles/new"

Mark For Destruction

Do you have some complicated logic or criteria for deleting associated records? ActiveRecord's #mark_for_destruction may come in handy.

Let's say we have users who author articles. We want to delete some of the user's articles based on some criteria -- those articles that have odd ids.

> user = User.first
#=> #<User...>
> user.articles.each { |a| a.mark_for_destruction if a.id.odd? }
#=> [#<Article...>, ...]
> user.articles.find(1).marked_for_destruction?
#=> true
> user.articles.find(2).marked_for_destruction?
#=> false

We've marked our articles for destruction and confirmed as much with the #marked_for_destruction? method. Now, to go through with the destruction, we just have to save the parent record -- the user.

> user.save
   (0.2ms)  BEGIN
  User Exists (0.8ms)  SELECT  1 AS one FROM "users" WHERE ("users"."email" = 'person1@example.com' AND "users"."id" != 1) LIMIT 1
  SQL (3.0ms)  DELETE FROM "articles" WHERE "articles"."id" = $1  [["id", 1]]
  SQL (0.2ms)  DELETE FROM "articles" WHERE "articles"."id" = $1  [["id", 3]]
   (2.1ms)  COMMIT
=> true

Note: the parent record must have autosave: true declared on the association.

class User < ActiveRecord::Base
  has_many :articles, autosave: true
end

Convert A Symbol To A Constant

If you have a symbol and need to convert it to a constant, perhaps because of some metaprogramming induced by a polymorphic solution, then you may start off on an approach like the following. In fact, I've seen a number of StackOverflow solutions like this.

:module.to_s.capitalize.constantize
#=> Module

That is great for one-word constant names, but what about multi-word constants like OpenStruct. This approach will not work for the symbol :open_struct. We need a more general solution.

The key is to ditch #capitalize and instead use another ActiveSupport method,#classify`.

:open_struct.to_s.classify.constantize
#=> OpenStruct

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.

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

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

Range Into List Using Comprehensions

Using an identity comprehension and the :into option, we can easily convert a range into a list.

> for x <- 1..10, into: [], do: x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Check out the docs for the :into option for more details.

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)

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.

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.

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

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.

Root Directory Of A Project

Do you need the root directory of an elixir project? The File.cwd!/0 function can help.

iex> File.cwd!
"/home/dev/code/my_app"

Keep in mind though, this will only work reliably with projects that are compiled using Mix.

source

Render A Template To A String

Templates in a Phoenix application ultimately get compiled to functions that can be quickly rendered with the necessary data. We can take a look at how a template will be rendered using Phoenix.View.render_to_string/3.

First, we need a template:

# user.html.eex
<h1><%= @user.first_name %></h1>
<h5><%= @user.username %> (<%= @user.email %>)</h5>

We can then render that template for the view with some user:

> user = %User{first_name: "Liz", last_name: "Lemon", username: "llemon", email: "lizlemon@nbc.com"}
%MyApp.User{...}

> Phoenix.View.Render_to_string(MyApp.UserView, "user.html", user: user)
"<h1>Liz</h1>\n<h5>llemon (lizlemon@nbc.com)</h5>\n"

Checking Inequality

In most languages there is a != operator for checking inequality of two things.

Postgres also supports the synonymous <> operator for checking inequality.

> select 1 <> 1;
 ?column?
----------
 f

> select true <> false;
 ?column?
----------
 t

> select 'taco' <> 'burrito';
 ?column?
----------
 t

h/t Brian Dunn

source

Do You Have The Time? - Part 2

In Do You Have The Time?, I demonstrated a way of using an Erlang function to get at and work with time in Elixir. As of Elixir 1.3, there is now a Time module that provides a sigil and some functions for working with time.

We can use Elixir's Time module to simplify the example from the previous iteration of this TIL:

defmodule TickTock do
  def current_time do
    Time.from_erl!(:erlang.time)
    |> Time.to_string
  end
end

> TickTock.current_time
"19:58:12"

Check For A Substring Match

Using Erlang's :binary.match function, you can easily check if a string has a matching substring.

> :binary.match("all food is good", "foo")
{4, 3}
> :binary.match("all food is good", "bar")
:nomatch

As you can see, the return value on a successful match is a tuple with the index of where the match starts and the length of the match. If there is no match, the :nomatch atom is returned.

See the match/2 and match/3 docs for more details.

source

Do You Have The Time?

Elixir doesn't come with any standard ways of getting at or working with time. There are packages like Timex out there that we can pull in to our projects. However, if we don't have need for a full-featured date/time library, we can opt for a simpler solution.

Erlang can give us the time.

defmodule TickTock do
  def current_time do
    {hh,mm,ss} = :erlang.time
    "#{hh}:#{mm}:#{ss}"
  end
end

> TickTock.current_time
"11:47:13"

Or Operator Precedence

What's the difference between || and or in Ruby?

Let's look at an example to find out. First, let's start with some boolean variables:

> a, b = false, true
=> [false, true]

Now, let's try the different or operators:

> a || b
=> true
> a or b
=> true

Cool, they seem to work as expected.

Finally, let's capture the result in a variable:

> c = a or b
=> true
> c
=> false

But why is c false and not true? Operator precedence. The assignment operator (=) takes precedence over the or operator causing c to be assigned to the value of a (false) before or'd with b.

source

Advance The Date

In Rails land, you can advance a date forward and backward with the #advance method:

> Date.today
=> Wed, 31 Aug 2016
> Date.today.advance(days: 1)
=> Thu, 01 Sep 2016
> Date.today.advance(months: 1)
=> Fri, 30 Sep 2016
> Date.today.advance(months: -2)
=> Thu, 30 Jun 2016

h/t Dillon Hafer

Expand Emojis With The Spread Operator

There are a number of emojis that are not stand-alone unicode characters, but instead are a combination of two or more other emojis. The two main places this happens is with family emojis and emojis using non-simpsons skin tones.

You can use JavaScript's spread operator to expand these emojis to see what their base components are. Here is a screenshot of a few that I expanded from Chrome's dev tools.

source

Documentation Lookup With Vim and Alchemist

Which argument position is the accumulator for Enum.reduce/3?

How does group_by work?

I find myself fairly frequently jumping from vim to Chrome to do Google searches for Elixir standard lib documentation. It gets the job done, but it is kinda slow and I'd prefer to avoid the context switch.

With alchemist.vim, Elixir documentation lookup is at your finger tips. Just move the cursor over the module or function you are curious about and hit K (from normal mode).

Curious about Enum.reduce? Type it out in your current Vim buffer, move the cursor over it, and hit K.

Updating Values In A Map

When working with maps in any language, you often need a way to update key-value pairs. Furthermore, you will need a way to handle keys that are not already present in the map, generally associating some default value.

In Elixir, the Map module provides the get_and_update/3 function as a way of accomplishing such a task.

Let's use a score counting example to see it in action:

> scores = %{}
%{}
# jake scores a point
> {_, scores} = Map.get_and_update(scores, :jake, fn(x) -> {x, (x || 0) + 1} end)
{nil, %{jake: 1}}
# chris scores a point
> {_, scores} = Map.get_and_update(scores, :chris, fn(x) -> {x, (x || 0) + 1} end)
{nil, %{chris: 1, jake: 1}}
# jake scores another point
> {_, scores} = Map.get_and_update(scores, :jake, fn(x) -> {x, (x || 0) + 1} end)
{1, %{chris: 1, jake: 2}}
# final scores
> scores
%{chris: 1, jake: 2}

We use (x || 0) + 1 as a way of providing an initial score for new keys.

The update function is expected to return a tuple with the original value and the updated value.

See the docs for more details.

Rotate Everything By 13 Letters

For some inane reason, Vim comes with a ROT-13 feature. So, if you are ever in need of rotating the letters of some portion of the file by 13, you can do that with the simple g? binding.

For example, if you hit g?? on the following line:

Six dollar eggs

you will get

Fvk qbyyne rttf

As you can see, casing is preserved.

The only practical uses of this are Vimgolf and convincing people at coffee shops that you are a hacker.

See :h g? for more details.

Show Matching Entries For Help

Looking up things with Vim's :help command can be error prone if you don't know exactly how to format what you are looking up. Bypass some of the guesswork by hitting Ctrl-d after writing part of the :help command. This will populate a wildmenu of possible matches.

For instance, if you know there is a command containing ?, but you aren't sure how to look it up, try the following:

:help ?<Ctrl-d>

You can tab through to the one you want and hit enter to read up on it. Who knew there were so many Vim bindings involving a ?.

See :h help-context for more details.

Checking Commit Ancestry

I have two commit shas and I want to know if the first is an ancestor of the second. Put another way, is this first commit somewhere in the history of this other commit.

Git's merge-base command combined with the --is-ancestor flag makes answering this question easy. Furthermore, because it is a plumbing command, it can be used in a script or sequence of commands as a switch based on the answer.

Here is an example of this command in action:

$ git merge-base --is-ancestor head~ head && echo 'yes, it is'
yes, it is
$ git merge-base --is-ancestor head~ head~~ && echo 'yes, it is'

In the first command, head~ is clearly an ancestor of head, so the echo command is triggered. In the second, head~ is not an ancestor of head~~ so the return status of 1 short-circuits the rest of the command. Hence, no echo.

See man git-merge-base for more details.

source

List Different Commits Between Two Branches

There are times when I want to get a sense of the difference between two branches. I don't want to look at the actual diff though, I just want to see what commits are on one and the other.

I can do just this by using the git-log command with a couple flags, most importantly the --cherry-pick flag.

To compare the feature branch against the master branch, I can run a command like the following:

$ git log --left-right --graph --cherry-pick --oneline feature...branch

This lists commits with the first line of their messages. It also includes either a < or > arrow at the front of each commit indicating whether the commit is on the left (feature) or right (master) branch, respectively.

Note: you can use more than branches in a command like this. Any two references will work. You can just use two SHAs for instance.

source

Jump To The Ends Of Your Shell History

There are all sorts of ways to do things in your shell environment without reaching for the arrow keys. For instance, if you want to move up to the previous command, you can hit Ctrl-p. To move down to the next command in your shell history, you can hit Ctrl-n.

But what if you want to move to the beginning and end of your entire shell history?

Find your meta key (probably the one labeled alt) and hit META-< and META-> to move to the end and beginning of your shell history, respectively.

source

Binary Representation Of A String

A common trick in Elixir is to concatenate the null byte <<0>> to a string to see its inner binary representation.

A couple example of this can be seen in the following snippet of code:

> "hello" <> <<0>>
<<104, 101, 108, 108, 111, 0>>
> "ƒå®øü†" <> <<0>>
<<198, 146, 195, 165, 194, 174, 195, 184, 195, 188, 226, 128, 160, 0>>

source

List Names Of Files With Matches

I often use grep and ag to search for patterns in a group or directory of files. Generally I am interested in looking at the matching lines themselves. However, sometimes I just want to know the set of files that have matches. Both grep and ag can be told to output nothing more than the names of the files with matches when given the -l flag.

This can come in particularly handy if you just want a list of files that can be piped (or copied) for use with another command. This eliminates all the extra noise.

h/t Dillon Hafer

Reversing A List

To efficiently work with and transform lists in Elixir, you will likely need utilize a list reversing function from time to time. Your best bet is to reach for the Erlang implementation which is available as part of the lists module.

Here are a couple examples of how to use it:

> :lists.reverse([1,2,3])
[3, 2, 1]
> :lists.reverse([1, :a, true, "what", 5])
[5, "what", true, :a, 1]

Note: though I said _transform_ lists above, what is actually going on is that a new version of the list representing my transformation is being created, per Elixir's functional nature.

Reset Target tslime Pane

The combination of tslime and turbux makes running tests from Vim in a tmux session as easy as a single key binding. One problem that can arise from time to time is having tslime focused on an undesired tmux window/pane combination. There is no binding to tell tslime that you'd like to re-select the target window and pane.

I've often resorted to closing out of Vim in order to reset the prompt. There is a better way and it doesn't require you to wipe out your Vim session.

Just unlet the global Vim variable for the tslime plugin like so:

:unlet g:tslime

The next time you invoke turbux it will see that g:tslime isn't set and will prompt you for a new window and pane combination.

h/t Josh Davey

Dynamically Generating Atoms

Atoms are constants where their name is their own value.

The use of atoms like :ok and :error show up all over the place in Elixir. These are atoms that tend to be statically defined. Atoms can also be dynamically defined using string interpolation.

For example, I can generate a handful of atoms by mapping over a range of integers.

> Enum.map(1..5, &(:"some_atom_#{&1}"))
[:some_atom_1, :some_atom_2, :some_atom_3, :some_atom_4, :some_atom_5]

Note: atoms are not garbage collected. If you dynamically generate atoms in excess, you may run your VM out of heap space.

List Of Sessions To A Machine

The last command is a handy way to find out who has been connecting to a machine and when.

Last will list the sessions of specified users, ttys, and hosts, in reverse time order. Each line of output contains the user name, the tty from which the session was conducted, any hostname, the start and stop times for the session, and the duration of the session. If the session is still continuing or was cut short by a crash or shutdown, last will so indicate.

In particular, this can be useful for finding an IP address that you want to connect to.

See man last for more details.

Assert An Exception Is Raised

Elixir's ExUnit comes with a number of different ways to make assertions in your tests. One of those functions is assert_raise which allows you to test that a particular exception is raised when the given function is invoked.

Using assert_raise/2 looks something like this:

assert_raise FunctionClauseError, fn ->
  Enum.chunk([1,2,3], 0)
end

The assert_raise/3 form is also available which allows you to test both the type of exception and the resulting message.

assert_raise FunctionClauseError, ~r/^no function clause matching/, fn ->
  Enum.chunk([1,2,3], 0)
end

Using the regex sigil for the second argument is generally a good way to go to keep tests from getting too brittle.

String Interpolation With Just About Anything

Coming to Elixir from Ruby, I am used to being able to interpolate literally anything into a string. In Elixir, this is not the case.

By default, it handles strings, atoms (including nil, true, false and module name aliases like String – which are all just atoms behind the scenes), integers, floats, and some lists. That's it.

There are two approaches you can take to interpolate everything else into a string. The easier approach is to use Kernel.inspect/2.

> IO.puts "A map #{inspect %{a: 1, b: 2}}"
A map %{a: 1, b: 2}

The other approach is to implement the String.Chars protocol for the thing that you are trying to print. You can read more about that in Elixir String Interpolation for Rubyists.

Pattern Matching In Anonymous Functions

Pattern matching shows up everywhere in Elixir, even where you may not be expecting it. When declaring an anonymous function, you can use pattern matching against different sets and shapes of input parameters to invoke different behaviors.

Here is an example of how you might use this:

> handle_result = fn
  {:ok, result} -> IO.puts "The result is #{result}"
  :error -> IO.puts "Error: couldn't find anything"
end
#Function<6.50752066/1 in :erl_eval.expr/5>

> Map.fetch(%{a: 1}, :a) |> handle_result.()
The result is 1
:ok
> Map.fetch(%{a: 1}, :b) |> handle_result.()
Error: couldn't find anything
:ok

source

Quitting IEx

There are two ways to quit out of an Interactive Elixir shell. The standard way is with Ctrl-c. This gives you a list of options, one of which is a for abort. This will terminate your IEx session and drop you back on the command line where the process started.

Additionally, IEx also understands Ctrl-\ which is control key that will terminate just about any interactive environment. This command will cause IEx to immediately exit with no prompt.

Note: IEx does not, however, respond to Ctrl-d.

source

Diffing With Patience

The default diff algorithm used by Git is pretty good, but it can get mislead by larger, complex changesets. The result is a noisier, misaligned diff output.

If you'd like a diff that is generally a bit cleaner and can afford a little slow down (you probably can), you can instead use the patience algorithm which is described as such:

Patience Diff, instead, focuses its energy on the low-frequency high-content lines which serve as markers or signatures of important content in the text. It is still an LCS-based diff at its core, but with an important difference, as it only considers the longest common subsequence of the signature lines:

Find all lines which occur exactly once on both sides, then do longest common subsequence on those lines, matching them up.

You can set this as the default algorithm by adding the following lines to your ~/.gitconfig file:

[diff]
    algorithm = patience

or it can be set from the command line with:

$ git config --global diff.algorithm patience

source

h/t Josh Davey

Create A Date With The Date Sigil

Elixir 1.3 introduced a new sigil for creating dates, ~D. It works in the same way as Date's new/3 function producing the Date struct with each of the date parts.

> ~D[2016-01-01]
~D[2016-01-01]
> ~D[2016-01-01].year
2016
> ~D[2016-01-01].month
1
> ~D[2016-01-01].day
1

Execute Raw SQL In An Ecto Migration

If you are performing a database migration with Ecto, perhaps the most straightforward approach is to use Ecto's DSL. However, the DSL may not always be the best choice. Being able to write raw SQL gives you more control. It will also enable you to use database features that may not be directly or easily available through the DSL.

Raw SQL can be included in a Ecto migration with a combination of Elixir's heredoc syntax and the Ecto.Migration#execute/1 function. You'll also need to provide both an up and down function to ensure that your migrations are reversible.

defmodule MyApp.Repo.Migrations.CreatePostsTable do
  use Ecto.Migration

  def up do
    execute """
      create table posts (
        id serial primary key,
        title varchar not null,
        body varchar not null default '',
        inserted_at timestamptz not null default now(),
        updated_at timestamptz not null default now()
      );
    """
  end

  def down do
    execute "drop table posts;"
  end
end

Word Lists For Atoms

The ~w sigil works similarly to Ruby's %w (word array notation). It allows you to create a list of words (i.e. strings).

> ~w(one two three)
["one", "two", "three"]

It sets itself apart though with some modifiers. The default behavior matches the s modifier (for strings).

> ~w(one two three)s
["one", "two", "three"]

Where it gets more interesting is with the a modifier allowing you to create a list of atoms.

> ~w(one two three)a
[:one, :two, :three]

Note: there is a third modifier, c, for char lists.

> ~w(one two three)c
['one', 'two', 'three']

source

List Functions For A Module

During an iex session, I can do a little introspection on modules using either the __info__/1 function or Erlang's module_info/0 function. In particular, I can pass :functions to either one to get a list of the functions for that module.

This is what __info__/1 looks like for the functions of the List module:

> List.__info__(:functions)
[delete: 2, delete_at: 2, duplicate: 2, first: 1,
 flatten: 1, flatten: 2, foldl: 3, foldr: 3, insert_at: 3,
 keydelete: 3, keyfind: 3, keyfind: 4, keymember?: 3,
 keyreplace: 4, keysort: 2, keystore: 4, keytake: 3,
 last: 1, replace_at: 3, to_atom: 1, to_existing_atom: 1,
 to_float: 1, to_integer: 1, to_integer: 2, to_string: 1,
 to_tuple: 1, update_at: 3, wrap: 1, zip: 1]

source

Blank Lines Above And Below

Generally when I want to add a line above or below the line that the cursor is on, I use O and o, respectively. This has a couple potential drawbacks. First and most prominent, the cursor is moved to the new line and left in insert mode. Usually, I'd like to remain in normal mode and stay on the current line. Second, these commands will emulate indentation and other formatting rules. This is either exactly what you want or a bit of an annoyance.

The vim-unimpaired plugin provides an alternative worth adding to your toolbelt. By hitting [<space> and ]<space>, a new line will be opened above and below the current line, respectively. Additionally, it leaves you in normal mode, keeps the cursor on the current line, and moves the cursor to the first non-indented character. In the case of performing this command in the midst of a comment in a source code file, neither the indentation nor the comment character will be propagated onto the new line.

Hold on to O/o and [<space>/]<space> and know the difference. You'll likely need each of them from time to time.

h/t Josh Davey

Open The Current Command In An Editor

If you are working with a complicated command in the terminal trying to get the arguments just right. Such as this curl:

curl https://api.stripe.com/v1/customers \
   -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
   -d description="Customer for test@example.com" \
   -d source=tok_189fCz2eZvKYlo2CsGERUNIW

It can be tedious to move to and modify various parts of the command. However, by hitting Ctrl-x Ctrl-e, the contents of the command buffer will be opened into your default editor (i.e. $EDITOR). This will make editing the command a bit easier. Saving and quitting the editor will put the updated command in the command buffer, ready to run.

Hit Ctrl-x Ctrl-e with an empty command buffer if you want to start crafting a command from scratch or if you are pasting one in from somewhere.

h/t Josh Davey

Setting Filetype With Modelines

Vim and various plugins generally use known file extensions to determine the filetype of a file. This is important because it is how Vim decides which filetype-specific settings to enable, such as syntax highlighting.

If I am editing a file such as build.boot, Vim is not going to know that its filetype should be set to clojure. The build.boot file is full of clojure code though, so I'm losing out on syntax highlighting and so forth. I can settle for manually setting the filetype to clojure (e.g. :set ft=clojure) each time I open up the file.

Or I can use a modeline setting. By including a comment at the top or bottom of the file specifying the filetype setting, I can ensure that each time I go to edit the file, the appropriate filetype will be set.

That modeline comment will look something like:

; vim: set ft=clojure:

See :h modeline for more details.

h/t Brian Dunn

Require Entire Gemfile In Pry Session

Want to experiment in a pry session with some of the gems in your project's Gemfile? You can quickly require all the gems for your project using Bundler's #require method.

Just require bundler itself and then execute Bundler.require. Everything will be loaded in.

> require 'bundler'
=> true
> Bundler.require
=> [Gem::Dependency.new("devise", Gem::Requirement.new([">= 0"]), :runtime),
 Gem::Dependency.new("rails", Gem::Requirement.new(["= 4.2.5"]), :runtime),
 Gem::Dependency.new("pg", Gem::Requirement.new(["~> 0.15"]), :runtime),
...

Read-Only Models

Are you in the midst of a big refactoring that is phasing out an ActiveRecord model? You may not be ready to wipe it from the project, but you don't want it accidentally used to create any database records. You essentially want your model to be read-only until it is time to actually delete it.

This can be achieved by adding a readonly? method to that model that always returns true.

def readonly?
  true
end

ActiveRecord's underlying persistence methods always check readonly? before creating or updating any records.

source

h/t Josh Davey

Where Am I In The Partial Iteration?

Let's say I am going to render a collection of posts with a post partial.

<%= render collection: @posts, partial: "post" %>

The ActionView::PartialIteration module provides a couple handy methods when rendering collections. I'll have access in the partial template to #{template_name}_iteration (e.g. post_iteration) which will, in turn, give me access to #index, #first?, and #last?.

This is great if I need to do something special with the first or last item in the collection or if I'd like to do some sort of numbering based on the index of each item.

source

h/t Josh Davey

Globbing For All Directories In Zsh

Globbing in Zsh is an expressive way to generate filenames for commands. This includes working with directories. If I'd like to run a command against all directories in the current directory, I can employ the *(/) globbing pattern.

$ echo *(/)
one three two

What about all directories in the root directory?

$ echo /*(/)
/Applications /Library /Network /System /Users /Volumes /bin /cores /dev /home /net /opt /private /sbin /usr

You can go ahead and use that with any other command now (e.g. ls).

source

Globbing For Filenames In Zsh

Zsh has extensive support for globbing for filenames. Globbing is a short-hand, of sorts, for generating filenames that meet certain criteria. The generated filenames can be used with any command you might otherwise provide a filename to in a unix setting.

For example, consider a directory full of files including many that are named with numbers. You'd like to list all files that have numeric names.

Doing ls by itself gives the following result:

$ ls
10        11        2         3         4         801       92        code.rb   hello.txt

With the use of a numeric pattern, Zsh's globbing helps ls limit the set of listed files to just those with numeric names:

$ ls *[0-9]
10  11  2   3   4   801 92

This only scrapes the surface of what can be done with globbing in Zsh.

source

h/t Josh Davey

String Interpolation With Instance Variables

When using regular variables with string interpolation in Ruby, they must be wrapped in curly braces (e.g. "This is a #{variable}"). With instance variables (and class and global variables) you can just use the octothorp followed directly by the variable.

Here is an example of this in action:

class Person
  def initialize(name)
    @name = name
  end

  def whoami
    puts "I am #@name"
  end
end

bob = Person.new("bob")
#=> #<Person:0x007fdaf3291618 @name="bob">

bob.whoami
# I am bob

This is a handy shortcut, but may affect readability and/or result in an interpolation error at some point. Your mileage may vary.

h/t Josh Davey

Create A Hash From An Array Of Arrays

The ::[] method on the Hash class allows you to succinctly create a hash from an array of arrays -- or rather an array of tuples which are key value pairs.

> Hash[ [["a",2],["b",4]] ]
{"a"=>2, "b"=>4}
> Hash[ [[1,2],[3,4]] ]
{1=>2, 3=>4}

See the Hash::[] docs for more details.

h/t Josh Davey

PID Of The Current Shell

$ expands to the process ID of the shell. So, you can see the PID of the current shell with echo $$.

> echo $$
36609

> zsh

> echo $$
45431

> exit

> echo $$
36609

See the Special Paramaters section of man bash for more details.

source

Edit Previous Parts Of The Pry Buffer History

Each line of Ruby you enter into a Pry session is recorded with a number in the buffer history. Pry keeps this buffer history so that you can recall parts of it for editing and subsequent execution.

If you use the edit command by itself, Pry will open the previous Ruby statement in your default editor. But what if you want to edit a statement from a while back? Or even a series of statements?

Use the --in flag with edit either specifying a single record in the buffer history or a range of records.

$ pry
[1] pry(main)> puts "Hello"
Hello
=> nil
[2] pry(main)> puts "World"
World
=> nil
[3] pry(main)> puts "People"
People
=> nil
[4] pry(main)> edit --in 1..2
Hello
World
=> nil

Assumed Radius Of The Earth In PostgreSQL

Using the earthdistance module, we can get the assumed radius of the earth (in meters).

> create extension cube;
CREATE EXTENSION

> create extension earthdistance;
CREATE EXTENSION

> select earth();
  earth
---------
 6378168

Show Disk Usage For The Current Directory

The du utility can be used to show disk usage for a particular directory or set of directories. When used without any arguments, it will show the disk usage for the current directory.

$ du
80      ./.git/hooks
8       ./.git/info
256     ./.git/logs/refs/heads
...

with the -h command we can see it all in a human-readable format

$ du -h
 40K    ./.git/hooks
4.0K    ./.git/info
128K    ./.git/logs/refs/heads

and to get an even clearer picture we can pipe that through sort -nr

$ du -h | sort -nr
412K    ./vim
352K    ./postgres
340K    ./.git/logs
216K    ./.git/logs/refs
184K    ./ruby
156K    ./unix
148K    ./git
...

This sorts it numerically in reverse order putting the largest stuff at the top.

Sort In Numerical Order

By default, the sort command will sort things alphabetically. If you have numerical input though, you may want a numerical sort. This is what the -n flag is for.

If I have a directory of files with numbered names, sort doesn't quite do the job by itself.

$ ls | sort
1.txt
10.txt
11.txt
12.txt
2.txt
3.txt
4.txt
5.txt

with the -n flag, I get the sort order I am looking for.

$ ls | sort -n
1.txt
2.txt
3.txt
4.txt
5.txt
10.txt
11.txt
12.txt

List Functions For A Namespace

You know that clojure.string has a function for uppercasing a string, but you can't quite remember the name of the function. You'd remember if you saw the name though. What you'd like to do is list all the functions in the clojure.string namespace to see if you can pick it out.

You can do just that. There are a couple ways to do it, in fact.

You can use the dir function with Clojure 1.6+. Alternatively, you can grab all the keys from the public intern mappings of the namespace.

> (dir clojure.string)
blank?
capitalize
ends-with?
escape
includes?
index-of
join
last-index-of
lower-case
re-quote-replacement
replace
replace-first
reverse
split
split-lines
starts-with?
trim
trim-newline
triml
trimr
upper-case
nil

> (keys (ns-publics 'clojure.string))
(ends-with? capitalize reverse join replace-first starts-with? escape last-index-of re-quote-replacement includes? replace split-lines lower-case trim-newline upper-case split trimr index-of trim triml blank?)

source

Determining The Age Of Things

In PostgreSQL, we can determine the age of something (or someone) by passing a timestamp to the age function.

For instance, if we want to know how long it has been since y2k, we can run the following query:

> select age(timestamp '2000-01-01');
           age
-------------------------
 16 years 4 mons 12 days

Additionally, if we want to know the amount of time between two dates, we can pass two timestamps to the age function.

For example, we can find out how old Prince lived to be by passing in the date of death and then date of birth:

> select age(timestamp 'April 21, 2016', timestamp 'June 7, 1958');
           age
--------------------------
 57 years 10 mons 14 days

h/t Josh Davey

Exclude A Directory With Find

Using find is a handy way to track down files that meet certain criteria. However, if there are directories full of irrelevant files, you may end up with a lot of noise. What you want to do is exclude or ignore such directories. For example, you probably don't want find to return results from the .git directory of your project.

Specific directories can be excluded by combining the -not and -path arguments.

For instance, to see all files modified within the last 10 days, but not including anything in the .git directory, run the following:

$ find . -type f -not -path './.git/*' -ctime -10

source

Read In The Contents Of A Rails File

The rails.vim plugin allows you to quickly navigate to specific types of files with the E prefix. For instance, :Emodel will scope you to just the models directory.

You can use this same approach with the D prefix. Instead of navigating to the specified file though, this will read in the contents of that file into the current buffer.

Do you need to copy and tweak the contents of a similar view? Open up your new view file (e.g. :Eview posts/edit.html.erb) and then enter :Dview posts/new to quickly copy in its contents.

h/t Josh Davey

Resizing Both Corners Of A Window (On Mac)

Hold the option key while resizing a corner of a window and it will simultaneously and equivalently resize the opposite corner.

Dump And Restore A PostgreSQL Database

PostgreSQL comes with two command-line utilities for dumping and then restoring a database -- pg_dump and pg_restore, respectively.

Using the pg_dump with the -Fc flag will create a dump of the given database in a custom format. The output of this command can be redirected into a file (the .dump extension is a standard convention):

$ pg_dump -Fc my_database > my_database.dump

Using the custom format option provides a couple benefits. The output is significantly compressed in comparison to a generic SQL dump. The dump and restoration is more flexible. Lastly, the dump can be performed in parallel if your machine has multiple cores to work with. Likewise, the restoration can be done in parallel with multiple jobs.

To restore the dump, create a fresh database and then use pg_restore:

$ createdb my_new_database
$ pg_restore -d my_new_database my_database.dump

Note: the dumped tables will depend on some user role. You will need to ensure that this role exists on the database cluster where the restore is happening. You can use the createuser command if necessary.

See the pg_dump docs and pg_restore docs for more details.

SSH Escape Sequences

In Killing A Frozen SSH Session, I talked about an escape sequence for breaking out of an SSH session when the pipe has been broken. This isn't the only SSH escape sequence though. To see the others, hit <Enter>~?. This displays a help list with all the other escape sequences.

> ~?
Supported escape sequences:
 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

h/t Josh Davey

List Database Objects With Disk Usage

I'll often times use \d or \dt to check out the tables in my database. This shows the schema, object name, object type (e.g. table), and owner for each.

By adding the + to that meta-command, I can also see the disk usage for each database object.

Here is an example of look at all tables in a database with the additional Size (or disk usage) information:

> \dt+
                              List of relations
 Schema |        Name        | Type  |   Owner    |    Size    | Description
--------+--------------------+-------+------------+------------+-------------
 public | amount_types       | table | jbranchaud | 16 kB      |
 public | ingredient_amounts | table | jbranchaud | 8192 bytes |
 public | ingredient_types   | table | jbranchaud | 16 kB      |
 public | ingredients        | table | jbranchaud | 48 kB      |
 public | recipes            | table | jbranchaud | 16 kB      |
 public | schema_migrations  | table | jbranchaud | 16 kB      |
 public | users              | table | jbranchaud | 16 kB      |

Get The Size Of An Index

Want to get an idea of how much disk space that additional index is taking up? In PostgreSQL, you can query for it with the same methods discussed in Get The Size Of A Table and Pretty Print Data Sizes.

For instance, if I have a table with a users_pkey index and a users_unique_lower_email_idx index, I can check the sizes like so:

> select pg_size_pretty(pg_relation_size('users_pkey'));
 pg_size_pretty
----------------
 240 kB

> select pg_size_pretty(pg_relation_size('users_unique_lower_email_idx'));
 pg_size_pretty
----------------
 704 kB

source

Perform SQL Explain With ActiveRecord

Want to check out the performance characteristics of some SQL query from within a Pry session? ActiveRecord allows you to perform a SQL explain on any ActiveRecord::Relation object. After chaining some Arel functions together, add an #explain.

Here is an example:

Recipe.all.joins(:ingredient_amounts).explain
  Recipe Load (0.9ms)  SELECT "recipes".* FROM "recipes" INNER JOIN "ingredient_amounts" ON "ingredient_amounts"."recipe_id" = "recipes"."id"
=> EXPLAIN for: SELECT "recipes".* FROM "recipes" INNER JOIN "ingredient_amounts" ON "ingredient_amounts"."recipe_id" = "recipes"."id"
                                 QUERY PLAN
----------------------------------------------------------------------------
 Hash Join  (cost=1.09..26.43 rows=22 width=148)
   Hash Cond: (ingredient_amounts.recipe_id = recipes.id)
   ->  Seq Scan on ingredient_amounts  (cost=0.00..21.00 rows=1100 width=4)
   ->  Hash  (cost=1.04..1.04 rows=4 width=148)
         ->  Seq Scan on recipes  (cost=0.00..1.04 rows=4 width=148)
(5 rows)

source

Change The Current Directory For psql

When you start a psql session, your current directory is what psql will use as its current directory. This is important for meta-commands that use relative paths based on the current directory -- for instance, the \i meta-command for importing files.

You can change the current directory within a psql session using the \cd meta-command.

If my current directory is home and there is a sql directory in `home, these commands will do the following:

\! pwd
-- /home
\cd sql
\! pwd
-- /home/sql

The \cd meta-command even supports tab completion relative to the current directory.

You can also change to your home directory using just \cd.

Use Not Valid To Immediately Enforce A Constraint

When adding a constraint to a table, you can optionally include not valid. This tells Postgres that it doesn't need to enforce the constraint on existing records in the table. At least not immediately. This constraint will be enforced for any updates and subsequent insertions. Thus, you can immediately enforce the constraint while giving yourself time to clean up or massage any existing records that conflict with the constraint.

Here is an example of how you would add a constraint this way:

alter table boxes
add constraint check_valid_length
check (length > 0) not valid;

Eventually, you will want to ensure that all data in the table conforms to the constraint. Once you get to that point, you can mark the constraint as valid with a validate constraint command:

alter table boxes
validate constraint check_valid_length;

As long as all records are valid with respect to this constraint, it will be marked as valid.

h/t Chris Erin

Lower Is Faster Than ilike

There are a couple ways to do a case-insensitive comparison of data in PostgreSQL. One way is to use the ilike operator for comparison. Another way is to use the lower() function on both sides of the = operator for comparison. Using lower() is a bit faster than using ilike.

When comparing

select * from users where email ilike 'some-email@example.com';

to

select * from users where lower(email) = lower('some-email@example.com');

we find (via explain analyze) that using lower() was taking around 12ms where as the ilike example was taking around 17ms.

We earn orders of magnitude in performance when adding a functional index that uses the lower() function like so:

create unique index users_unique_lower_email_idx on users (lower(email));

After adding this index, the example using lower() drops to around 0.08ms.

For the full example and explain analyze outputs, see this document.

Add ON DELETE CASCADE To Foreign Key Constraint

The alter table command lets you do quite a bit. But when it comes to altering existing constraints, there is not much you can do. If you want to add an on delete cascade to an existing foreign key constraint, you are going to need two statements.

The first statement will drop the constraint and the second statement will recreate it with the addition of the on delete clause. Furthermore, you'll want to do this in a transaction to ensure the integrity of your data during the transition between indexes.

Here is an example:

begin;

alter table orders
drop constraint orders_customer_id_fkey;

alter table orders
add constraint orders_customer_id_fkey
foreign key (customer_id)
references customers (id)
on delete cascade;

commit;

source

Print The Query Buffer In psql

I'll often be composing a PostgreSQL query in Vim and decide I want to give it a try in psql. I copy the relevant snippet of SQL to my system buffer and then paste into psql. I'm usually hit with a mess of text like this though:

jbranchaud=# create table nullable_fields (
jbranchaud(#   id serial primary key,
  first varchar,
  last varchar
)
  id serial primary key,
jbranchaud(#   first varchar,
  last varchar
)
  first varchar,
jbranchaud(#   last varchar
)
  last varchar
jbranchaud(# )
)
jbranchaud-#

Yikes. That's not readable. Fortunately, psql provides a command for printing the current contents of the query buffer. By typing \p I'll see a more readable version of what I just pasted in.

jbranchaud-# \p
create table nullable_fields (
  id serial primary key,
  first varchar,
  last varchar
)
jbranchaud-#

After taking another glance at the snippet of SQL, I decide to complete the query to create my new table.

jbranchaud-# ;
CREATE TABLE

Using Expressions In Indexes With PostgreSQL

Though we usually see column names by themselves when defining an index, it is also possible to create an index with an expression.

Let's say I have a users table with an email column. Then I may end up creating an index like this

create index email_idx on users (email);

If I always perform queries on the email column with the lower() function, like this

select * from users where lower(email) = lower('some@email.com');

then I will want to also create an index with that full expression -- lower(email)

I can do this with a statement like the following

create index lower_email_idx on users (lower(email));

Without an index that uses the full lower(email) expression, select statements like the one above will be forced to do full sequential scans instead of indexed scans.

List Various Kinds Of Objects

Our PostgreSQL database can end up with all kinds of objects: tables, sequences, views, etc. We can use a variety of psql meta-commands to list the different types of (user-created) objects in our database.

  • \dt will list all the tables
  • \dE will list all the foreign tables
  • \di will list all the indexes
  • \ds will list all the sequences
  • \dv will list all the views
  • \dm will list all the materialized views

These can also be combined. For instance, to see all the tables and sequences, we can run \dts.

Creating Custom Types in PostgreSQL

PostgreSQL has support for creating custom types. When you need something more expressive than the built-in types and you don't want your data spread across multiple columns, you can instead create a custom type.

create type dimensions as (
  width integer,
  height integer,
  depth integer
);

This new type can then be used in the definition of a new table

create table moving_boxes (
  id serial primary key,
  dims dimensions not null
);

and when inserting data

insert into moving_boxes (dims) values (row(3,4,5)::dimensions);

See the create type docs for more details.

Show All Versions Of An Operator

We may be familiar with PostgreSQL's containment operator (@>). Maybe we've used it with an array before, so we understand the general idea. But now we are curious about what are the other types with which this containment operator can be used.

We can quickly find out the answer with the \do command in psql:

> \do @>
                               List of operators
   Schema   | Name | Left arg type | Right arg type | Result type | Description
------------+------+---------------+----------------+-------------+-------------
 pg_catalog | @>   | aclitem[]     | aclitem        | boolean     | contains
 pg_catalog | @>   | anyarray      | anyarray       | boolean     | contains
 pg_catalog | @>   | anyrange      | anyelement     | boolean     | contains
 pg_catalog | @>   | anyrange      | anyrange       | boolean     | contains
 pg_catalog | @>   | jsonb         | jsonb          | boolean     | contains
...

The Left arg type and Right arg type columns tell us what we need to know.

This \do command can be used with any operator for a similar set of information.

h/t Bruce Momjian

Combinations Of Items From A Sequence

Sometimes we want all combinations of items from a list. For instance, we may have 5 people and we want to know all the ways that we can unique pair up 2 people from that group of 5. What we want is the number of combinations of 2 people from the 5.

The clojure/math.combinatorics library provides a combinations function that gives us exactly that functionality.

(use '[clojure.math.combinatorics :as combo])

(combo/combinations ["Liz", "Tracy", "Kenneth", "Jack", "Jenna"] 2)
; (("Liz" "Tracy") ("Liz" "Kenneth") ("Liz" "Jack")
;  ("Liz" "Jenna") ("Tracy" "Kenneth") ("Tracy" "Jack")
;  ("Tracy" "Jenna") ("Kenneth" "Jack") ("Kenneth" "Jenna")
;  ("Jack" "Jenna"))

The combinations function takes a list of items and then a number for the size of the grouping combinations that it is supposed to produce.

Demodulize A Class Name

If you call .class.name on an instance of some class, the fully qualified name will be returned, module names and all. Consider the following example class:

module One
  module Two
    class Three
      ...
    end
  end
end
> One::Two::Three.new.class.name
#=> "One::Two::Three"

If you just want the unqualified class name; modules not included, you can use the #demodulize method provided by ActiveSupport.

> One::Two::Three.new.class.name.demodulize
#=> "Three"

Timing Processes

If you want to time a process, you can use the console.time() and console.timeEnd() utilities specified by the console Web API. Invoking console.time() with a label starts a named timer. You can then run the process you want to time. Then invoke console.timeEnd() with the same label to terminate the timer and see how long the process took.

console.time('sorting');
[11,10,9,8,7,6,5,4,3,2,1].sort();
console.timeEnd('sorting');
> sorting: 0.278ms

console.time('console logging');
console.log('logging to the console');
console.timeEnd('console logging');
> logging to the console
> console logging: 0.311ms

console.time('adding'); 1 + 1; console.timeEnd('adding');
> adding: 0.006ms

These functions are implemented in most modern browsers.

See the docs for more details.

Better Module Imports With Webpack Aliases

Depending on how your JavaScript project is structured, you can end up with import statements that look like this:

import SomeComponent from 'app/assets/javascripts/components/SomeComponent.jsx';

or this:

import SomeComponent from '../components/SomeComponent.jsx';

The first is simply too long and the second is both ugly and brittle to changes in file location. This can all be resolved with a Webpack alias.

// webpack.config.js
resolve: {
  alias: {
    components: "app/assets/javascripts/components",
  },
},

Webpack will use this alias when resolving module imports like the following updated example:

import SomeComponent from 'components/SomeComponent.jsx';

See the resolve.alias section of the Webpack docs for more details.

h/t Vidal Ekechukwu

Add Emoji To GitHub Repository Description

GitHub restricts the set of unicode characters that can appear in the description field of a repository to anything up to 0xffff. Most emoji have unicode values above this. This means you will have limited success adding emoji via your system's emoji keyboard.

Fortunately, GitHub allows you to add any recognized emoji to a repository description with its specialized emoji syntax (e.g. :memo:). You may have used this syntax in other parts of GitHub such as the issue tracker.

If you add an emoji like this:

it will show up like so:

Check out this Emoji Cheat Sheet for the names of all recognized emojis.

Use Active Window With BufExplorer

I often use BufExplorer within long-running Vim sessions as a way of quickly jumping between the various buffers in my buffer list. After working with one buffer, I use <leader>bs to open BufExplorer, move my cursor to the next buffer of interest, and hit enter to open it in place of the current buffer. This is the default behavior at least.

With this setting toggled on, BufExplorer will open buffers in the active window. The active window is the window that was active before BufExplorer was opened. If this setting is toggled off, BufExplorer doesn't bother finding the active window, it just opens the buffer up in place of itself in whatever split window was created for itself.

This setting can be toggled within the BufExplorer window by hitting f. It will toggle between Locate Buffer and Don't Locate Buffer. I prefer the default of Locate Buffer.

h/t Vidal Ekechukwu

Load A Directory Of Files Into The Buffer List

Consider the scenario where I want to go through all files in a directory to make a series of minor, related changes. After editing each file, I can type something like :e path/to/next/file.md to bring up the next file. That can get a bit tedious though. Instead, I can load up all the files in the directory with the args command:

:args path/to/files/*.md

From there, I can use :bnext (or :bn) and:bprev` to more quickly jump through those files I want to edit.

I can also run :ls to see all the files loaded in to the buffer list at that point.

source

Running A Single MiniTest Example

Consider the following MiniTest file:

# test_stuff.rb
require 'minitest/autorun'

class TestStuff < MiniTest::Unit::TestCase
  def test_first_thing
    assert_equal 4, (2 * 2)
  end

  def test_second_thing
    assert_equal 9, (3 * 3)
  end
end

If we want to run all the tests in this file, we can do so with:

$ ruby test_stuff.rb

But what if we want to run a specific test? We can target a single MiniTest example with the --name flag and the name of that example. We can do something like the following:

$ ruby test_stuff.rb --name test_second_thing

source

Running ES6 Specs With Mocha

If your JavaScript specs contain ES6 syntax, Mocha, by default, will not be able to interpret and run them. In order to run them with Mocha, you will need to tell Mocha to use something like Babel to compile them. The --compile flag can be used to point Mocha to the babel-core/register package.

$ mocha --compilers js:babel-core/register path/to/specs/*.spec.js

If you already have a test command specified in your package.json file, you can update it with the --compile portion of the above command.

This all assumes you've already setup your project with Babel and Babel presets.

source

Clear The Screen In psql

The psql interactive terminal does not have a built-in way of clearing the screen. What I usually do if I really need the screen cleared is quit, run clear from the shell, and then open a new psql session. This is unnecessary though. Instead, we can use the \! command to execute a shell command, in this case, the clear command.

> \! clear

This clears the screen in one step and keeps our current session running.

See the psql docs for more details.

Storing Emails With citext

Email addresses should be treated as case-insensitive because they are. If a user is trying to sign in with their email address, we shouldn't care if they type user@example.com or User@example.com. Both of those email addresses should be treated as equal and ultimately lead us to the same User record.

With the citext extension in PostgreSQL, we can create a column that acts as a case-insensitive text type. Any comparisons on a column of that type will internally have the lower function executed on the arguments.

The following example shows this in action:

create extension if not exists citext;

create table citext_emails (
  id serial primary key,
  email citext not null unique
);

insert into citext_emails (email) values ('LizLemon@nbc.com');

select * from citext_emails where email = 'lizlemon@nbc.com';
--  id |      email
-- ----+------------------
--   1 | LizLemon@nbc.com

See citext_emails.sql for a full example.

Command Line Length Limitations

The other day I tried to run a rm command on the contents of a directory with a LOT of files.

$ rm images/*

Instead of deleting the contents of the directory, the following message was displayed:

/bin/rm: cannot execute [Argument list too long]

Bash wanted to expand the entire command before executing it. It was too long. But what is too long?

It turns out that we can figure out the max length of commands with the following command:

$ getconf ARG_MAX

For me, the result is 262144.

source 1 and source 2

Numbers Are Empty

The lodash project comes with a ton of handy JavaScript utilities including the _.isEmpty() function. This is great for checking if Arrays, Objects, and Strings are empty. The following is how this function is defined in the docs:

Checks if value is an empty collection or object. A value is considered empty if it's an arguments object, array, string, or jQuery-like collection with a length of 0 or has no own enumerable properties.

Having not examined this definition too closely and because I primarily write Rails code from day to day, I conflated _.isEmpty() with the #blank? method provided by Rails' ActiveSupport. This holds true for the most part, but quickly defies expectations when it comes to numbers.

> _.isEmpty(1)
// true

Debugging With Full Source Maps From Webpack

After Webpack runs your JavaScript through various loaders, it no longer looks like the code you were writing in your editor. This can make debugging difficult when you inspect the source of an error in the browser's devtools. Fortunately, Webpack makes it easy to enhance debugging with full source maps of your code. Just add the following option to your Webpack config:

{
  devtool: "source-map",
  ...
}

This will generate a full source map with a filename that is something like bundle.js.map.

Note: this will slow down the webpack build process a bit.

Read more about the devtool configuration and all the possible options in the Webpack docs.

Accessing Arguments To A Function

The arguments object is available within any JavaScript function. It is an array-like object with all of the arguments to the function. Even if not all of the arguments are referenced in the function signature, they can still be accessed via the arguments object.

function argTest(one) {
  console.log(one);
  console.log(arguments);
  console.log(arguments[1]);
}

argTest(1);
// 1
// [1]
// undefined

argTest(1, 'two', true);
// 1
// [1,'two',true]
// 'two'

See the Arguments object docs on MDN for more details.

h/t Dorian Karter

Attach A File With Capybara

There are two ways to attach a file with Capybara. The more conventional way is with the attach_file method.

Assuming there is a form with a file input similar to the following:

<label for='data-file'>Data File</label>
<input type='file' name='data-file' />
attach_file('data-file', 'path/to/file.csv')

The first argument to attach_file is a locator which refers to the name attribute on the input tag.

If for some reason there is no name attribute on the input tag, the file can be attached with a standard find and set.

find('form input[type="file"]').set('path/to/file.csv')

Renaming A Table

Using the alter table command in PostgreSQL, you can rename an existing table. This command will also update any references to the table such as via foreign key constraints. Just run a command like the following:

alter table ingredient_types rename to item_types;

Note that this may result in breaking a number of conventions. Foreign keys, sequences, and constraints with names eponymous to the original table will no longer follow convention despite the references being updated. These can be renamed as well if desired.

See renaming_table.sql for a full example.

See the alter table docs for more details.

Pretty Print Tabular Data

Looking at a bunch of data in the Chrome dev tools console isn't great. It can be a bit difficult to read because of the way it is displayed. Fortunately, the Chrome dev tools come with a handy way of displaying tabular data, console.table(). If you give console.table an array of objects or array of arrays, it will format it in a table like so:

Reference The Selected Node

In the Chrome dev tools, if you've selected (highlighted) a node in the DOM, you can reference that node from the console with $0. This is handy if you are debugging or exploring certain parts of a page and need to run commands against that node. For instance, if you were to select the <html> node in the DOM, you could then programmatically check the lang attribute from the console like so:

> $0.lang
// "en-US"

If there is jQuery on the page and you've selected the node that contains all of the page's content, you can do something like the following:

> $($0).html('<h1>Hello, World!</h1>')

Initialize Objects With Shorthand Property Names

If I have some variables:

const one = 1,
  two = 2,
  three = 3;

and I'd like to initialize an object with them, I'll generally do something like the following:

const obj1 = {
  one: one,
  two: two,
  three: three
};
// Object { one: 1, two: 2, three: 3 }

That seems pretty standard, but with ES6 comes a feature called shorthand property names which makes that look verbose and redundant. If you already have properly named variables, they can be used as a short hand for both the key name and variable value:

const obj2 = {
  one,
  two,
  three
};
// Object { one: 1, two: 2, three: 3 }

See the MDN Docs for Object Initializer for more details.

Open Vim To A Tag Definition

If you are using ctags with Vim, you can provide a tag name when opening Vim. This signals to Vim that it should open to the file and location of the tag's definition. For instance, if you have a Rails project going and you provide Vim with the UsersController tag name, it will open the app/controllers/users_controller.rb. Just use the -t flag like so:

$ vim -t UsersController

See man vim for more details.

Immutable Remove With The Spread Operator

ES6 introduces the spread operator which allows you to expand arrays in place for function calls, array composition, array destructuring, etc. One thing the spread operator allows you to concisely do with array composition is perform immutable operations on arrays. For instance, to remove an item from an array by index, you can throw together the following function.

const remove = (items,index) => {
  return [...items.slice(0,index),
          ...items.slice(index+1,items.length)];
};

const list = [1,2,3,4,5];
remove(list, 2);
// [1,2,3,4]
list
// [1,2,3,4,5]

It only took a couple lines of code and immutability is baked in.

There may be a couple edge cases that are not handled in this solution (e.g. remove(list, -1)), but you get the general idea.

Open The Latest Rails Migration

The rails.vim plugin comes with a lot of handy helpers for quickly navigating to many parts of a Rails project. Among these helpers is the :Emigration command that makes it easy to tab complete and navigate to Rails migration files. Often times the migration you want is the latest migration. There is no need for tab complete here, just type:

:Emigration

By default this command opens the latest migration in a new buffer.

See :h rails-:Emigration for more details.

Custom Validation Message

When using Rails validations, a standard error message will be provided whenever there is a violation. Consider the scenario when there is a uniqueness validation on the email attribute and it is violated:

# User model
validates_uniqueness_of :email

# Users controller
new_user.errors.full_messages
#=> ["Email has already been taken"]

Sometimes you don't want the default validation message. The validation declaration can be given a message option to specify an alternate validation message.

# User model
validates_uniqueness_of :email, message: 'is not available'

# Users controller
new_user.errors.full_messages
#=> ["Email is not available"]

Keep in mind that full_messages will prepend the model name to the front of the message. You'll want to ensure that the resulting message is coherent.

Open A Tag In A Split Window

Using tags and ctrl-] is a quick way to jump from the use of a keyword to the declaration or definition whether in the same file or another file. Sometimes what you really want is that tag definition opened up in a (horizontal) split window. That way you can see the definition without losing context. This can be accomplished with ctrl-w ].

The Vim help file gives the following definition of this command:

Use identifier under cursor as a tag and jump to it in the new upper window.

See :h CTRL-W_] for more details.

h/t Dorian Karter

Salt And Hash A Password With Postgres' pgcrypto

The pgcrypto extension that ships with PostgreSQL can be used to do a number of interesting things. This includes functions for doing salted password hashing. Using the crypt and gen_salt functions, we can securely store a user password and later compare it to plain-text passwords for authentication purposes.

create extension pgcrypto;

select crypt('pa$$w0rd', gen_salt('bf'));
                            crypt
--------------------------------------------------------------
 $2a$06$Z7wmrkYMOyLboLcULUYzNe6nHUcWywSZTt6nSrT5Xdv/VLdJ4g99K

> select (
    '$2a$06$Z7wmrkYMOyLboLcULUYzNe6nHUcWywSZTt6nSrT5Xdv/VLdJ4g99K' =
    crypt(
      'pa$$w0rd',
      '$2a$06$Z7wmrkYMOyLboLcULUYzNe6nHUcWywSZTt6nSrT5Xdv/VLdJ4g99K'
    )
  ) as matched;
 matched
---------
 t

> select (
    '$2a$06$Z7wmrkYMOyLboLcULUYzNe6nHUcWywSZTt6nSrT5Xdv/VLdJ4g99K' =
    crypt(
      'password',
      '$2a$06$Z7wmrkYMOyLboLcULUYzNe6nHUcWywSZTt6nSrT5Xdv/VLdJ4g99K'
    )
  ) as matched;
 matched
---------
 f

The salt value is generated using the blowfish encryption algorithm (hence, the 'bf'). There is support for other algorithms such as md5.

See the pgcrypt documentation for more details.

Truncate Almost All Tables

The database_cleaner gem is a handy way to make sure you have a consistent database context for each test example or suite. One database_cleaner strategy that can be used is the truncation strategy. This truncates the data from all the tables by default. This is not ideal for fixed tables that contain domain-specific data because you end up having to do way more test setup than should be necessary. Fortunately, specific tables can be excepted by the truncation strategy using the except option.

For instance, if we have a standard set of roles for users of our application, we can except that table from truncation with a line like the following in our rails_helper.rb file:

DatabaseCleaner.strategy = :truncation, {:except => %w[roles]}

Last Argument Of The Last Command

You can use !$ as a way to reference the last argument in the last command. This makes for an easy shortcut when you want to switch out commands for the same long file name. For instance, if you just ran cat on a file to see its contents

$ cat /Users/jbranchaud/.ssh/config

and now you want to edit that file. You can just pass !$ to the vim command:

$ vim !$

Hit enter or tab to get the full command:

$ vim /Users/jbranchaud/.ssh/config

h/t Dorian Karter

Show All Commits For A File Beyond Renaming

By including -- <filename> with a git log command, we can list all the commits for a file. The following is an example of such a command with some formatting and file names.

> git log --name-only --pretty=format:%H -- README.md
4e57c5d46637286731dc7fbb1e16330f1f3b2b7c
README.md

56955ff027f02b57212476e142a97ce2b7e60efe
README.md

5abdc5106529dd246450b381f621fa1b05808830
README.md

What we may not realize, though, is that we are missing out on a commit in this file's history. At one point, this file was renamed. The command above wasn't able to capture that.

Using the --follow flag with a file name, we can list all commits for a file beyond renaming.

> git log --name-only --pretty=format:%H --follow README.md
4e57c5d46637286731dc7fbb1e16330f1f3b2b7c
README.md

56955ff027f02b57212476e142a97ce2b7e60efe
README.md

5abdc5106529dd246450b381f621fa1b05808830
README.md

ea885f458b0d525f673623f2440de9556954c0c9
README.rdoc

This command roped in a commit from when README.md used to be called README.rdoc. If you want to know about the full history of a file, this is the way to go.

source

Interact With The Alternate File

If you have a couple buffers going in a Vim session and you check out the buffer list with :ls, you'll notice that one of those buffers has a # indicator next to it. That means the file for this buffer is considered the alternate file of the current, visible buffer. In addition to hitting CTRL-^ to switch to that buffer, you can reference it in other commands with #. This means you can quickly :edit, :split, :vsplit, and so forth the alternate file by just giving # as the argument to those commands.

Quickly open the alternate file in a vertical split with:

:vsp #

See :h alternate-file for more details.

Close All Other Windows

Opening split windows can be useful in a number of circumstances. Eventually though, you are going to want to go back to just one window. Generally when this happens to me, I navigate to each of the other split windows that I don't want and execute :q. What I want to do is essentially close all the other split windows except for my current one. Vim provides a single command for doing this. By hitting

<CTRL>w <CTRL>o

all other windows are closed leaving the current window as the only one on the screen.

If you want this command to be able to work with windows containing modified buffers, you are going to want to have the hidden option turned on.

See :h CTRL-W_CTRL-O for more details.

Delete To The End Of The Line

There are a number of ways to delete from the cursor position to the end of the line. Generally when I am doing this, I want delete to the end of the line and then start typing something different. Perhaps the best way to do this is by hitting C. It deletes to the end of the line and then leaves you in insert mode. This also makes for easier repetition with the dot command.

This is synonymous with hitting c$.

See :h C for more details.

h/t Dorian Karter

Kill Other Connections To A tmux Session

One of the best features of tmux is the ability for multiple people to connect to the same session in order to pair. This can, however, sometimes result in a extra session hanging around if someone forgets to detach. This is no problem though because you can view and kill other connections.

Hit

<prefix>D

to open up an interactive list of all connections to the current session. Then navigate over the one you want to kill and hit enter. If you are viewing the connections but don't want to kill one, you can hit q to back out.

h/t Josh Davey

List The Statuses Of All Upstart Jobs

To see a list of all known upstart jobs and their statuses, use the following command:

$ initctl list
...
console stop/waiting
mounted-run stop/waiting
acpid start/running, process 2927
checkfs.sh start/running
checkroot-bootclean.sh start/running
kmod stop/waiting
mountnfs.sh start/running
nginx stop/waiting
plymouth-stop stop/waiting
rcS stop/waiting
ufw start/running
...

It will tell you for each job if it is stopped or started.

See man initctl for more details.

h/t Josh Davey

Almost The End Of The Line

If you are visually selecting from the cursor to the end of the line, you will probably hit:

v$

This isn't always ideal though because the visual selection includes the newline character at the end of the line. If instead you'd like to motion to the last non-blank character on the line you can use the g_ motion. This is great for deleting to the end of the line.

dg_

See :h g_ for more details.

h/t Dorian Karter

Terminating A Connection

Consider the scenario where you are trying to drop a database, but there are existing connections.

$ dropdb sample_db
dropdb: database removal failed: ERROR:  database "sample_db" is being accessed by other users
DETAIL:  There is 1 other session using the database.

If you don't know where these connections are, you can terminate them within a psql session. You just have to figure out the pid of those connections. In List Connections To A Database, I explained how to get at the pid values of connections. Using the pid value and pg_terminate_backend(), you can terminate a connection.

> select pg_terminate_backend(12345);
 pg_terminate_backend
----------------------
 t

To terminate all connections to a particular database, use a query like the following:

select pg_terminate_backend(pg_stat_activity.pid)
from pg_stat_activity
where pg_stat_activity.datname = 'sample_db'
  and pid <> pg_backend_pid();
 pg_terminate_backend
----------------------
 t

This excludes the current session, so you'll need to exit psql as well before dropping the database.

source

Deleting Buffers In BufExplorer

The BufExplorer plugin makes it easy to browse and navigate to the various buffers open in a Vim session. It is based on your buffer list. After a bit of coding, your buffer list can start to get a bit out of control. There are surely going to be buffers that you want to close out, delete if you will.

Within the BufExplorer browser you can move your cursor onto a buffer and delete it.

To delete it by unloading the buffer (see :h bd), you can hit d.

To delete it by wiping out the buffer (see :h bw), you can hit D.

If you already have the plugin installed, see :h bufexplorer for more details.

List Connections To A PostgreSQL Database

The pg_stat_activity table can be used to determine what connections there currently are to the PostgreSQL server and to a particular database. To see the process ids and usernames of all connection to your PostgreSQL server, run the following query:

> select pid, usename from pg_stat_activity;
  pid  |  usename
-------+------------
 57174 | jbranchaud
 83420 | jbranchaud

Include datname in the requested columns to figure out the database of each connection.

> select pid, usename, datname from pg_stat_activity;
  pid  |  usename   |  datname
-------+------------+-----------
 57174 | jbranchaud | hr_hotels
 83420 | jbranchaud | pgbyex

The results can be restricted to a particular database as necessary.

> select pid, usename from pg_stat_activity where datname = 'hr_hotels';
  pid  |  usename
-------+------------
 57174 | jbranchaud

Create Thumbnail Image For A PDF

The rmagick gem is a wrapper around the ImageMagick software suite. This gem can be used to create a thumbnail image of a PDF using the following snippet of code.

require 'rmagick'
pdf = Magick::ImageList.new('document.pdf')
first_page = pdf.first
scaled_page = first_page.scale(300, 450)
scaled_page.write('document-thumbnail.jpg')

The scale can be adjust as necessary to the use case.

source

Show The diffstat Summary Of A Commit

Use the --stat flag when running git show on a commit to see the diffstat summary of that commit. For instance, this is what I get for a recent commit to delve:

$ git show 8a1f36a1ce --stat
commit 8a1f36a1ce71d708d1d82afbc2191de9aefba021
Author: Derek Parker <derek.parker@coreos.com>
Date:   Wed Jan 27 23:47:04 2016 -0800

    dlv: Flag to print stacktrace on trace subcommand

 cmd/dlv/main.go     | 45 ++++++++++-----------------------------------
 terminal/command.go |  7 +++++--
 2 files changed, 15 insertions(+), 37 deletions(-)

The following is a description of the diffstat program

This program reads the output of diff and displays a histogram of the insertions, deletions, and modifications per-file.

See man git-show and man diffstat for more details.

Expose Internal Representation

Elixir is a language that has strong support for metaprogramming. It provides easy access to an internal representation of the code in the form of an Abstract Syntax Tree (AST) using maps and keyword lists. The quote macro is used to expose this internal representation.

> quote do: 2 * 2
{:*, [context: Elixir, import: Kernel], [2, 2]}
> quote do: 2 * 2 == 4
{:==, [context: Elixir, import: Kernel],
 [{:*, [context: Elixir, import: Kernel], [2, 2]}, 4]}

source

Sets With The Values Command

You can concisely create sets of values in PostgreSQL using the values command.

> values (1), (2), (3);
 column1
---------
       1
       2
       3

You can even create multiple columns of values.

> values (1, 'a', true), (2, 'b', false);
 column1 | column2 | column3
---------+---------+---------
       1 | a       | t
       2 | b       | f

This is most often used with an insert command, but can be used on its own, as a subquery, within a CTE, etc.

source

Listing All Rows In A Table

In PostgreSQL, perhaps the more common way to list all rows in a table is with the following select command:

select * from bedding_types;

There is an alternative approach that also selects all rows from a table. It's essentially a shorthand -- the table command.

> table bedding_types;
   name
----------
 No Bed
 1 Full
 1 Double
 2 Double
 1 Twin
 2 Twins
 1 Queen
 2 Queen
 1 King
 2 Kings
 3 Kings
 Murphy
 Sofa Bed

h/t Jack Christensen

Append To A Keyword List

If you have two keyword lists, you can append them like so:

> a = [a: 1]
[a: 1]
> b = [b: 2]
[b: 2]
> a ++ b
[a: 1, b: 2]

But what if something a bit more programmatic is happening and you are building up the additions to the keyword list based on variables?

> x = :x
:x
> c = a ++ [x 5]
** (CompileError) iex:5: undefined function x/1
    (stdlib) lists.erl:1353: :lists.mapfoldl/3
    (stdlib) lists.erl:1354: :lists.mapfoldl/3

That makes elixir think x is some function when in fact it is just a variable containing the keyword :x.

Simply adding a comma doesn't quite do it either.

> c = a ++ [x, 5]
[{:a, 1}, :x, 5]

We need to wrap the internal part with curly braces to create the tuple that can then be appended to a.

> c = a ++ [{x, 5}]
[a: 1, x: 5]

List Available Schemas

Use the \dn command within a psql session to list the available schemas. This will only included user created schemas. This means that schemas like public will be listed whereas schemas like information_schema and pg_catalog will not.

You can use \dnS to also list system schemas.

source

Rename The Current tmux Session

If you've created an unnamed tmux session or you no longer like the original name, you can open a prompt to change it by hitting

<prefix>$

Replace the existing name with the desired name and hit enter.

h/t Dorian Karter

Build And Install A Go Program

With the vim-go plugin, Vim gets all kinds of support for working with a Go project. Generally, with a Go project, you have to run go build to compile the project and if that is successful, you can run go install to put the executable binary on the $GOPATH.

This plugin allows you to tighten the feedback loop. You can build right within your Vim session using

:GoBuild

which will alert you to any compilation errors.

You can then install the program using

:GoInstall

Your program is now ready to run.

It's worth noting that this plugin will also notify you about syntax errors when you save, if they exist.

Sleep For A Duration

Many languages allow you to sleep for a certain number of milliseconds. In those languages, you can give 500 or 1000 to the sleep function to sleep for half a second and a second respectively. In Go, the duration of a call to time.Sleep is in nanoseconds. Fortunately, there are constants that make it easy to sleep in terms of milliseconds.

For example, you can sleep for a half a second (500 milliseconds) like so:

package main

import (
    "time"
)

func main() {
    time.Sleep(500 * time.Millisecond)
}

Other available time constants are Nanosecond, Microsecond, Second, Minute, Hour.

If You Detect None

The Enumerable#detect method, which is synonymous with #find, can be given an optional argument, ifnone, that is called when nothing in the array meets the conditional in the block. Though I am not sure how this is practically useful and cannot find an example of it in use, this contrived example illustrates how it works.

# without the fallback behavior
> [2,4,6,8].detect { |x| x.odd? }
=> nil

# with a proc as an argument
> [2,4,6,8].detect(->{0}) { |x| x.odd? }
=> 0

The last example can also be written as:

> [2,4,6,8].detect(->{0}, &:odd?)
=> 0

And if you want to be really explicit:

> [2,4,6,8].detect(ifnone=->{0}, &:odd?)
=> 0

Set A Seed For The Random Number Generator

In PostgreSQL, the internal seed for the random number generator is a run-time configuration parameter. This seed parameter can be set to a particular seed in order to get some determinism from functions that utilize the random number generator. The seed needs to be something between 0 and 1.

We can see this in action by setting the seed and then invoking random() a couple times. Doing this twice, we will see the reproducibility we can achieve with a seed.

> set seed to 0.1234;
SET

> select random();
      random
-------------------
 0.397731185890734

> select random();
      random
------------------
 0.39575699577108
(1 row)

> set seed to 0.1234;
SET

> select random();
      random
-------------------
 0.397731185890734

> select random();
      random
------------------
 0.39575699577108

The seed can also be configured with the setseed() function.

See the PostgreSQL docs for more details.

Pretty Print Data Sizes

Use the pg_size_pretty() function to pretty print the sizes of data in PostgreSQL. Given a bigint, it will determine the most human-readable format with which to print the value:

> select pg_size_pretty(1234::bigint);
 pg_size_pretty
----------------
 1234 bytes

> select pg_size_pretty(123456::bigint);
 pg_size_pretty
----------------
 121 kB

> select pg_size_pretty(1234567899::bigint);
 pg_size_pretty
----------------
 1177 MB

> select pg_size_pretty(12345678999::bigint);
 pg_size_pretty
----------------
 11 GB

This function is particularly useful when used with the pg_database_size() and pg_relation_size() functions.

> select pg_size_pretty(pg_database_size('hr_hotels'));
 pg_size_pretty
----------------
 12 MB

Get The Size Of A Table

In Get The Size Of A Database, I showed a PostgreSQL administrative function, pg_database_size(), that gets the size of a given database. With the pg_relation_size() function, we can get the size of a given table. For instance, if we'd like to see the size of the reservations table, we can executing the following query:

> select pg_relation_size('reservations');
 pg_relation_size
------------------
          1531904

This gives us the size of the reservations table in bytes. As you might expect, the referenced table needs to be part of the connected database and on the search path.

See the Postgres docs for more details.

Get The Size Of A Database

If you have connect access to a PostgreSQL database, you can use the pg_database_size() function to get the size of a database in bytes.

> select pg_database_size('hr_hotels');
 pg_database_size
------------------
          8249516

Just give it the name of the database and it will tell you how much disk space that database is taking up.

Checkout the Postgres docs for more details.

Day Of Week By Name For A Date

In Day Of Week For A Date, I explained how to determine what day of the week a date is as an integer with PostgreSQL. This used the date_part() function. By using the to_char() function with a date or timestamp, we can determine the day of the week by name (e.g. Monday). For instance, to determine what day today is, try a statement like the following:

> select to_char(now(), 'Day');
  to_char
-----------
 Sunday

The Day part of the second argument is just one of many template patterns that can be used for formatting dates and times.

See Data Type Formatting Functions in the Postgres docs for more details.

Set Schema Search Path

By default the schema search path for a PostgreSQL database is going to be "$user", public. Tables created by a Rails migration are going to end up on the public schema by default. If your application has other schemas in play, then you may want to ensure that those schemas are also on the schema search path. This can be accomplished by adding the schema_search_path setting to your database.yml file. For instance, to include both the legacy and public schema in the Postgres search path, add the following line:

schema_search_path: "legacy,public"

h/t Jack Christensen

Day Of Week For A Date

Given a date in PostgreSQL

> select '2050-1-1'::date;
    date
------------
 2050-01-01

you can determine the day of the week for that date with the date_part() function

> select date_part('dow', '2050-1-1'::date);
 date_part
-----------
         6

The days of week are 0 through 6, 0 being Sunday and 6 being Saturday.

source

pg Prefix Is Reserved For System Schemas

Have you ever tried to create a schema with pg_ as the first part of the name of the schema? If so, you probably didn't get very far. Postgres won't let you do that. It reserves the pg_ prefix for system schemas. If you try to create a schema in this way, you'll get an unacceptable schema name error.

> create schema pg_cannot_do_this;
ERROR:  unacceptable schema name "pg_cannot_do_this"
DETAIL:  The prefix "pg_" is reserved for system schemas.

Escaping A Quote In A String

In PostgreSQL, string (varchar and text) literals are declared with single quotes ('). That means that any string containing a single quote will need some escaping. The way to escape a single quote is with another single quote.

> select 'what''s up!';
  ?column?
------------
 what's up!

source

Defaulting To Frozen String Literals

The cold never bothered me anyway.

The release of Ruby 2.2 introduced the ability to freeze string literals, making them immutable. With the release of Ruby 2.3, strings can be frozen by default without the use of #freeze. By adding the following magic comment at the top of a file

# frozen_string_literal: true

all string literals will default to frozen. That means that all string literals in that file are immutable, cannot be modified. This gives the Ruby interpreter some performance gains due to reduced object allocation.

This is the issue that introduced it.

Compute Hashes With pgcrypto

The pgcrypto extension that comes with PostgreSQL adds access to some general hashing functions. Included are md5, sha1, sha224, sha256, sha384 and sha512. Any of these hashing functions can be applied to an arbitrary string using the digest function. Here are example of the md5 and sha1 algorithms:

> create extension pgcrypto;
CREATE EXTENSION

> select digest('Hello, World!', 'md5');
               digest
------------------------------------
 \x65a8e27d8879283831b664bd8b7f0ad4

> select digest('Hello, World!', 'sha1');
                   digest
--------------------------------------------
 \x0a0a9f2a6772942557ab5355d76af442f8f65e01

See the pgcrypto docs for more details.

Returning With Sequel

The sequel gem is a database toolkit that allows you to interact with most databases. PostgreSQL has support for composite primary keys, but sequel, which is supposed to return the id of newly inserted records, isn't sure what to return when faced with a composite primary key. You can get around this by telling sequel exactly what should be returned using the #returning method. For instance, get it to return just the id of the new record:

DB[:floors].returning(:id).insert(hotel_id: 4, id: 1, ...)
# [{id: 1}]

To get it to return both parts of composite key:

DB[:floors].returning(:id, :hotel_id).insert(hotel_id: 4, id: 1, ...)
# [{id: 1, hotel_id: 4}]

Highlighting Search Matches

Want to see all the places in the buffer that match a search pattern? Turn on hlsearch and Vim will highlight all the matches of the previous search.

Try turning it on with :set hlsearch and then search for some pattern using /.

If you no longer want to see all the highlighted matches, turn it off with :set nohlsearch.

See :h hlsearch for more details.

Paste A Register From Insert Mode

Generally pasting a register is done from Normal mode using p or something like '1p (the former pasting from the default register, 0, and the latter pasting from register 1). Vim also allows you to paste from a register without leaving Insert mode. By hitting CTRL-R and then the name of the register, Vim will insert the contents of the register in front of the cursor.

For example, to paste from the default register from Insert mode, hit CTRL-R 0.

Note, mappings and abbreviations will not be applied to the inserted text.

See :h i_CTRL-R for more details.

h/t Chris Erin

Grep For Files Without A Match

The grep command is generally used to find files whose contents match a pattern. With the -L (--files-without-match) flag, grep can be used to find files that don't match the given pattern.

For instance, to find files in the current directory that don't have foobar anywhere in their content, run:

$ grep -L "foobar" ./*

source

Backspace Options

The backspace option determines the behavior of pressing the backspace key (<BS>). By default, Vim's backspace option is set to an empty list. There are three values that can be added that each independently alter the behavior of the backspace key. These are indent, eol, and start.

When indent is included, you can backspace over indentation from autoindent. Without it, Vim will not allow you to backspace over indentation.

When eol is included, you can backspace over an end of line (eol) character. If the cursor is at the first position of a line and you hit backspace, it will essentially be joined with the line above it. Without eol, this won't happen.

When start is included, you can backspace past the position where you started Insert mode. Without start, you can enter Insert mode, type a bit, and then when backspacing, only delete back as far as the start of Insert mode.

The backspace default is absurd, you are going to want to add all of the above to your Vim settings.

See :h 'backspace' for more details.

Breaking The Undo Sequence

Generally, the sequence of undo-able actions is segmented by command. When entering Insert mode, everything typed until exiting Insert mode is part of a single undo-able segment. If you are going to be typing in Insert mode for a while though, you may want to break it up a bit. Without leaving Insert mode, hit ctrl-g u to mark a break in the sequence of undos.

For example, starting in Normal mode and then typing iabc<CTRL-G>udef<CTRL-G>ughi<ESC> will leave the buffer with:

abcdefghi

Hitting u once will leave the buffer with:

abcdef

Hitting u again:

abc

Hitting ctrl-r:

abcdef

See :h i_CTRL-G_u for more details.

Aliasing An Ansible Host

When specifying the hosts that Ansible can interact with in the /etc/ansible/hosts file, you can put just the IP address of the host server, like so:

192.168.1.50

IP addresses are not particularly meaningful for a person to look at though. Giving it a name serves as better documentation and makes it easier to see what host servers are in play during a task.

Ansible makes it easy to alias host servers. For example, we can name our host staging like so:

staging ansible_host=192.168.1.50

source

Block Comments

Ruby supports (ugly) block comments. They look like this:

=begin
This is a block comment.

I can put whatever I want in here.
=end
def do_something
  ...
end

source

Load A File Into The REPL

You can quickly load a file into a REPL session using the load-file function. You can specify an absolute or relative path and it will

sequentially read and evaluate the set of forms contained in the file.

(load-file "path/to/file.clj")

See the load-file docs for more details.

Rendering ERB

If you have a string that contains ERB templating, you can quickly generate the resulting string with the following code snippet:

require 'erb'

some_template_string = <<-TEXT
The top
<% 5.times do |i| %>
Item <%= i + 1 %>
<% end %>
The bottom
TEXT

puts ERB.new(some_template_string).result

This will print the following to stdout:

The top
Item 1
Item 2
Item 3
Item 4
Item 5
The bottom

source

Difference Between :wq and :x

The :wq command is used in Vim to write and quit. The contents of the buffer are written to disk for the associated file and then the Vim session is terminated. So, what is the difference between this and the :x command. The Vim help files give the following description of the :x command:

Like :wq, but write only when changes have been made.

So, :wq writes the buffer to disk either way, whereas :x just exits if the buffer hasn't changed. Either way the contents of the resulting file are going to be the same. So what's the difference?

Modification time.

If you :x a buffer that hasn't changed, the modification time will be untouched because the file isn't re-saved. The :wq command will alter the modification time no matter what.

This matters if the modification time is used by anything. For instance, a background process that monitors a directory for changed files based on modification times will get some false positives if you use :wq too liberally.

source

Creating Conditional Constraints in PostgreSQL

There are times when it doesn't make sense for a constraint to apply to all records in a table. For instance, if we have a table of pokemon, we may only want to apply a unique index constraint to the names of non-wild pokemon. This can be achieved in PostgreSQL with the following conditional constraint:

create unique index pokemons_names on pokemons (names)
where wild = false;

If we try to insert a non-wild pokemon with a duplicate name, we will get an error. Likewise, if we try to update a pokemon with a duplicate name from wild to non-wild, we will get an error.

source

Identify Outdated Gems

Bundler can be used to identify outdated gems for a given project. By running bundle outdated in a project's directory, Bundler will compare the versions of all stated gem dependencies against the gem server and report a list of those gems that are not up to date.

See the Bundler docs for more details.

Show Rails Routes With Pry

In Show Rails Models With Pry, I showed that pry-rails comes with some handy console commands. In addition to being able to list all your Rails models, you can list all the routes for your application using show-routes.

I get the following output by using that command in a small blog project:

> show-routes
              Prefix Verb   URI Pattern                     Controller#Action
                root GET    /                               application#index
markdownify_articles POST   /articles/markdownify(.:format) articles#markdownify
            articles POST   /articles(.:format)             articles#create
         new_article GET    /articles/new(.:format)         articles#new
        edit_article GET    /articles/:id/edit(.:format)    articles#edit
             article GET    /articles/:id(.:format)         articles#show
                     PATCH  /articles/:id(.:format)         articles#update
                     PUT    /articles/:id(.:format)         articles#update
               users POST   /users(.:format)                users#create
            new_user GET    /users/new(.:format)            users#new
                user GET    /users/:id(.:format)            users#show
            sessions POST   /sessions(.:format)             sessions#create
         new_session GET    /sessions/new(.:format)         sessions#new
             session DELETE /sessions/:id(.:format)         sessions#destroy
              signin GET    /signin(.:format)               sessions#new
                     POST   /signin(.:format)               sessions#create
              signup GET    /signup(.:format)               users#new

Untrack A Directory Of Files Without Deleting

In Untrack A File Without Deleting It, I explained how a specific file can be removed from tracking without actually deleting the file from the local file system. The same can be done for a directory of files that you don't want tracked. Just use the -r flag:

$ git rm --cached -r <directory>

source

Sleeping In PostgreSQL

Generally you want your SQL statements to run against your database as quickly as possible. For those times when you are doing some sort of debugging or just want your queries to look very computationally expensive, PostgreSQL offers the pg_sleep function.

To sleep for 5 seconds, try the following:

> select now(); select pg_sleep(5); select now();
              now
-------------------------------
 2016-01-08 16:30:21.251081-06
(1 row)

Time: 0.274 ms
 pg_sleep
----------

(1 row)

Time: 5001.459 ms
              now
-------------------------------
 2016-01-08 16:30:26.252953-06
(1 row)

Time: 0.260 ms

As you'll notice, the pg_sleep statement took about 5 seconds.

source

Is It Null Or Not Null?

In PostgreSQL, the standard way to check if something is NULL is like so:

select * as wild_pokemons from pokemons where trainer_id is null;

To check if something is not null, you just add not:

select * as captured_pokemons from pokemons where trainer_id is not null;

PostgreSQL also comes with ISNULL and NOTNULL which are non-standard ways of doing the same as above:

select * as wild_pokemons from pokemons where trainer_id isnull;
select * as captured_pokemons from pokemons where trainer_id notnull;

Show Rails Models With Pry

With the pry-rails gem, you get some extra goodies in the Rails console for your project. One of those goodies is show-models, a command for printing out a list of all models in the rails project. Add and bundle the pry-rails gem, run rails c, and then run show-models to give it a go.

> show-models
Pokemon
  id: integer
  name: string
  level: integer
  pokemon_type: varchar
  belongs_to Trainer
  created_at: datetime
  updated_at: datetime
Trainer
  id: integer
  name: string
  has_many Pokemons

Enable ES7 Transforms With react-rails

The react-rails gem adds JSX and ES6 transforms to the asset pipeline. By using .js.jsx and .es6.jsx extensions with relevant files, the asset pipeline will know to make the appropriate transformation when compiling application assets. ES7 transforms are not enabled by default, but can be configured. Add the following to the config/application.js file to allow ES7's class properties syntax:

config.react.jsx_transform_options = {
  optional: ["es7.classProperties"]
}

h/t Mike Chau

Restarting Sequences When Truncating Tables

PostgreSQL's truncate feature is a handy way to clear out all the data from a table. If you use truncate on a table that has a serial primary key, you may notice that subsequent insertions keep counting up from where you left off. This is because the sequence the table is using hasn't been restarted. Sure, you can restart it manually or you can tell truncate to do it for you. By appending restart identity to the end of a truncate statement, Postgres will make sure to restart any associated sequences at 1.

truncate pokemons, trainers, pokemons_trainers restart identity;

Running Bundle With vim-bundler

The vim-bundler plugin is a companion of the rake.vim and rails.vim plugins. It is a lightweight plugin that exposes some bundler-related convenience methods.

The Vim :Bundle command exposes the bundle command. To install the latest changes to the Gemfile, you can invoke :Bundle or :Bundle install from inside of Vim.

Transforming ES6 and JSX with Babel 6

With Babel 5, transforming ES6 and JSX into ES5 code was accomplished by including the babel-loader. This would be configured in webpack.config.js with something like the following:

module: {
  loaders: [
    {
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'babel-loader',
    }
  ],
},

Now, with Babel 6, the different parts of the loader have been broken out into separate plugins. These plugins need to be installed

$ npm install babel-preset-es2015 babel-preset-react --save-dev

and then included as presets

module: {
  loaders: [
    {
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: 'babel-loader',
      query: {
        presets: ['es2015', 'react']
      },
    }
  ],
},

Alternatively, the presets can be specified in the project's .babelrc file.

Source

Pass A Block To Count

Ruby's Enumerable module comes with the method #count for determining how many items are in an array or hash.

> [1,2,3].count
=> 3
> {a: 1, b: 2}.count
=> 2

The #count method has a trick up its sleeve though. It can take a block with a predicate that returns true or false. It essentially acts like #select returning the count rather than the array subset itself.

> [1,2,3].count { |x| x.odd? }
=> 2
> {a: 1, b: 2}.count { |(x,y)| y < 0 }
=> 0

Grepping Through The Vim Help Files

Trying to look up the help file for a Vim feature, but you cannot quite remember the right keyword? Use :helpgrep. With :helpgrep, you can search across all of the Vim help files for not just the specific keywords, but any pattern of text. For instance, if you want to find where substitution is mentioned in the help files, try:

:helpgrep substitution

It makes a list of all occurrences in the quick fix window and then opens up a split with the cursor on the line of the first occurrence. You can then hit :copen to see the rest of the entries.

See :h helpgrep for more details.

Safe Navigation Operator

With the release of Ruby 2.3, the safe navigation operator (&.) is now available. This addition to the Ruby language allows you to collapse all those pesky nil checks into the accessor call they are guarding. Consider this snippet of common Ruby code:

if user && user.authenticate(params[:password])
  # proceed with logged in user
end

With the safe navigation operator, the predicate can now be collapsed:

if user&.authenticate(params[:password])
  # proceed with logged in user
end

If user is nil, then the predicate will evaluate to false and the body of the if-statement will be passed over.

Source

Two Ways To Compute Factorial in PostgreSQL

In PostgreSQL, there are two ways to compute the factorial of a number. There is a prefix operator and a postfix operator. The prefix operator is !! and can be used like so:

> select !!5;
 ?column?
----------
      120

The postfix operator is ! and can be used like so:

> select 5!;
 ?column?
----------
      120

See the mathematical functions and operators docs for more details.

Reference A Commit Via Commit Msg Pattern Matching

Generally when referencing a commit, you'll use the SHA or a portion of the SHA. For example with git-show:

$ git show cd6a63d014
...

There are many ways to reference commits though. One way is via regex pattern matching on the commit message. For instance, if you recently had a commit with a typo and you had included typo in the commit message, then you could reference that commit like so:

$ git show :/typo
Author: Josh Branchaud
Date: Mon Dec 21 15:50:20 2015 -0600

    Fix a typo in the documentation
...

By using :/ followed by some text, git will attempt to find the most recent commit whose commit message matches the text. As I alluded to, regex can be used in the text.

See $ man gitrevisions for more details and other ways to reference commits.

Source

Increment All The Numbers

Vim's substitution feature can be used for more than simple static text replacement. Each replacement can be the result of some operation on the original text. For instance, what if we'd like to increment all numbers in the buffer? We can achieve this by searching for all numbers and then using \= with submatch. Whenever the replacement string of a substitution starts with \=, the remainder of the string is evaluated as an expression.

Given the following text in our buffer:

1 2 a b c 45 123 1982

We can run the following substitution command:

:%s/\d\+/\=submatch(0)+1/g

This will transform all digits in the buffer, resulting in:

2 3 a b c 46 124 1983

Want to decrement all the numbers instead?

:%s/\d\+/\=submatch(0)-1/g

See :h sub-replace-expression for more details.

Resetting A Reset

Sometimes we run commands like git reset --hard HEAD~ when we shouldn't have. We wish we could undo what we've done, but the commit we've reset is gone forever. Or is it?

When bad things happen, git-reflog can often lend a hand. Using git-reflog, we can find our way back to were we've been; to better times.

$ git reflog
00f77eb HEAD@{0}: reset: moving to HEAD~
9b2fb39 HEAD@{1}: commit: Add this set of important changes
...

We can see that HEAD@{1} references a time and place before we destroyed our last commit. Let's fix things by resetting to that.

$ git reset HEAD@{1}

Our lost commit is found.

Unfortunately, we cannot undo all the bad in the world. Any changes to tracked files will be irreparably lost.

source

What Is The Current Branch?

This question can be answered with one of git's plumbing commands, rev-parse.

$ git rev-parse --abbrev-ref HEAD

The --abbrev-ref flag tells git-rev-parse to give us the short name for HEAD instead of the SHA.

source

Move The Latest Commit To A New Branch

I sometimes find myself making a commit against the master branch that I intended to make on a new branch. To get this commit on a new branch, one possible approach is to do a reset, checkout a new branch, and then re-commit it. There is a better way.

$ git checkout -b my-new-branch
$ git checkout - 
$ git reset --hard HEAD~

This makes better use of branches and avoids the need to redo a commit that has already been made.

Note: The example was against the master branch, but can work for any branch.

Paging Up And Down In tmux

When in copy mode (<prefix>[), you can move the cursor around like you would in vim with the directional keys (hjkl). This works fine until you want to move up or down through pages and pages of text, such as when navigating to the top of a long stack trace. One way to get where you need to be more quickly is by paging up and down.

Hit CTRL-u to page up and CTRL-d to page down.

PostgreSQL's Max Identifier Length Is 63 Bytes

In PostgreSQL, identifiers -- table names, column names, constraint names, etc. -- are limited to a maximum length of 63 bytes. Identifiers longer than 63 characters can be used, but they will be truncated to the allowed length of 63.

> alter table articles
    add constraint this_constraint_is_going_to_be_longer_than_sixty_three_characters_id_idx
    check (char_length(title) > 0);
NOTICE:  identifier "this_constraint_is_going_to_be_longer_than_sixty_three_characters_id_idx" will be truncated to "this_constraint_is_going_to_be_longer_than_sixty_three_characte"
ALTER TABLE

Postgres warns us of identifiers longer than 63 characters, informing us of what they will be truncated to. It then proceeds to create the identifier.

If postgres is trying to generate an identifier for us - say, for a foreign key constraint - and that identifier is longer than 63 characters, postgres will truncate the identifier somewhere in the middle so as to maintain the convention of terminating with, for example, _fkey.

The 63 byte limit is not arbitrary. It comes from NAMEDATALEN - 1. By default NAMEDATALEN is 64. If need be, this value can be modified in the Postgres source. Yay, open-source database implementations.

See the postgres docs for more details.

Coercing Casing With vim-abolish

The vim-abolish plugin provides a couple handy shortcuts for quickly coercing the casing of a variable.

For instance, if you have a variable in camel case and you want to change it snake case, you can navigate over the variable and hit crs (e.g. myFavoriteVariable -> my_favorite_variable).

Similarly, you can hit crc to change a variable to camel case.

It even has support for mixed case (crm) and uppercase (cru).

h/t Jake Worth

Splat Arguments To A Function

Often times you have a function that takes a certain set of arguments. Like the following adder function:

var adder = function(a,b,c) {
  return a + b + c;
};

But you are left trying to pass in arguments as an array (e.g. [1,2,3]). You want to be able to splat the array of arguments so that it matches the function declaration. This can be done by using apply.

> adder.apply(undefined, [1,2,3])
6

Change Default Shell For A User

You can change the default shell program for a particular unix user with the chsh command. Just tell it what shell program you want to use (e.g. bash or zsh) and which user the change is for:

$ [sudo] chsh -s /usr/bin/zsh username

This command needs to be invoked with root privileges.

This command updates the entry for that user in the /etc/passwd file.

source

Select A Select By Selector

Generally when using Capybara to select from a select input, I reference it by its name which rails associates with the label:

select("Charizard", from: "Pokemon")

However, not all forms are going to have a label paired with every select input. We don't want to let our test coverage suffer, so we are going to need a different way to select. Fortunately, Capybara allows us to chain select off a find like so:

find('#pokemon_list').select('Charizard')

Adding Composite Uniqueness Constraints (Postgres)

There are two ways in Postgres to create a composite uniqueness constraint; that is, a constraint that ensures that the combination of two or more values on a table only appear once. For the following two code snippets, assume that we have a table relating Pokemon and Trainers and that our domain restricts each Trainer to only having at most one of each Pokemon.

The first approach is to create a constraint directly on the table:

alter table pokemons_trainers
  add constraint pokemons_trainers_pokemon_id_trainer_id_key
  unique (pokemon_id, trainer_id);

The second approach is to create a unique index:

create unique index pokemons_trainers_pokemon_id_trainer_id_idx
  on pokemons_trainers (pokemon_id, trainer_id);

Argument Requirements For A Function

When defining a function, you must declare one or more function definitions, each of which will require a different set of arguments. These argument lists are stored as metadata for the function. So, if you are trying to figure out what arity a function is or what variations of arguments it takes, you can check the metadata like so:

> (:arglists (meta #'str))
([] [x] [x & ys])

source

Comparing Arrays In RSpec

Among its many built-in matchers, RSpec includes a set of array matchers. One of the array matchers is match_array which compares two arrays independent of ordering. This is handy if you need to check that a resulting array matches your expectations when ordering is unimportant and not necessarily deterministic. It can be used like so:

expect([1,2,3]).to match_array([3,2,1])

This expectation is met, the test will pass.

Opening Man Pages In Vim

In Quick Man Pages, I explained how you can quickly open man pages with K. For times when the particular command isn't in the buffer or the command contains a hyphen, you can instead use :Man. With the ft-man-plugin enabled, you can use :Man with the name of any command that has a manual page and the respective man page will be opened in a split buffer. For example, check out git log with:

:Man git-log

If you don't want the first manual entry, provide a specific number. For instance, you can open the echo(3) man page with:

:Man 3 echo

See :h :Man for more details.

Creating Non-Existent Directories

When creating new files from within vim, using :e, you may find yourself creating that file in a directory that doesn't yet exist. Vim will tell you as much if you then try to save that file. To get around this, I have often shelled out with :!mkdir %:h. This is a bit awkward to type though.

The vim-eunuch plugin comes with a handy command for this. :Mkdir will create the parent directory for the current buffer. If you're in a situation where multiple levels of the buffer's directory don't exist, you can use :Mkdir! which will invoke mkdir with the -p flag.

Grep Over Commit Messages

The git log command supports a --grep flag that allows you to do a text search (using grep, obviously) over the commit messages for that repository. For the git user that writes descriptive commit messages, this can come in quite handy. In particular, this can be put to use in an environment where the standard process involves including ticket and bug numbers in the commit message. For example, finding bug #123 can be accomplished with:

$ git log --grep="#123"

See man git-log for more details.

Jumping Between tmux Sessions

If you are using tmux to manage multiple projects by putting each project in a separate session, you may find yourself moving between sessions frequently. Detaching and reattaching can and will get tedious. There are better ways. tmux provides the <prefix>) and <prefix>( bindings as a way of jumping to the next and previous session, respectively. That should reduce some friction.

Params Includes Submission Button Info

When a form is submitted for a Rails app, the respective controller action will have access to a variety of information in the params hash. Included is an entry with the name and value of the button that submitted the form. By default, Rails will give the name commit to a submission button.

<%= f.submit %>
# results in:
<input type="submit" name="commit" value="Submit">Submit</input>

The corresponding create action will have parameters that include that submission button's info:

# in create action
> params['commit']
=> 'Submit'

This is useful when you have multiple buttons that submit the same form, but should have slightly different results in the corresponding action. Differentiating becomes easy when you can easily check which was used to submit the form. No javascript required.

Get The Value Of An Environment Variable

You can get the value of an environment variable on your system using the System/getenv function. Just pass it the environment variable as a string:

> (System/getenv "HOME")
"/Users/jbranchaud"

It returns nil when the environment variable doesn't exist.

> (System/getenv "HOUSE")
nil

Aggregation Using merge-with

Clojure provides the merge-with function as a way of conjoining a series of maps. You must provide merge-with a function that it can use to merge two values for matching keys. For instance, imagine you have a bunch of maps that contain counts for entities identified by keywords. You can consolidate the sum of all the counts into a single map using the merge-with function combined with the + function.

> (merge-with + {:a 1 :b 3} {:b 2 :c 3} {:c 1 :d 4})
{:a 1, :b 5, :c 4, :d 4}

For different kinds of data, a different function argument may be more appropriate. For instance, aggregating lists instead of integers calls for the concat function:

> (merge-with concat {:a '(1 2) :b '(3 4)} {:c '(3 4) :a '(5 4 1)})
{:a (1 2 5 4 1), :b (3 4), :c (3 4)}

Try A Clojure Project In The REPL

The lein-try plugin is a tool that makes it easy to quickly try out a clojure project in the lein repl. Given the name and version of a clojure project, it will drop you into a repl with that project loaded in. This is a great way to get the feel for the features of an unfamiliar clojure library before dropping it in as a dependency to your own project.

First, add the plugin to your ~/.lein/profiles.clj file by including the following line in the :plugins vector:

[lein-try "0.4.3"]

Then simply invoke the plugin with whatever project you want to try:

$ lein try automat

And to include a specific version number:

$ lein try automat "0.1.3"

Pretty Print The Last Thing

Clojure provides pp as a convenience macro for pretty printing the last thing that was output. If you are playing around with a function in the repl, trying to get the output just right, pp can come in handy.

> (fancy-func)
{:one {:a 1, :b 2, :c 3, :d 4}, :two {:b 2, :c 3, :d 4, :e 5}, :three {:c 3,
:d 4, :e 5, :f 6}, :four {:d 4, :e 5, :f 6, :g 7}}
> (clojure.pprint/pp)
{:one {:a 1, :b 2, :c 3, :d 4},
 :two {:b 2, :c 3, :d 4, :e 5},
 :three {:c 3, :d 4, :e 5, :f 6},
 :four {:d 4, :e 5, :f 6, :g 7}}
nil

See (doc pp) for more details.

Add A File Without Loading It

Generally, when you interact with files (e.g. :e some-file.txt), you are both adding it to the buffer list and loading the contents of the file as a separate buffer. The :bad command allows you to add a file to the buffer list without loading it. For instance, you can add your README.md to the buffer list and leave the current buffer in focus with:

:bad README.md

This command seems particularly useful for scripting the setup of an initial vim environment or preparing for a :bufdo command.

Export Query Results To A CSV

Digging through the results of queries in Postgres's psql is great if you are a programmer, but eventually someone without the skills or access may need to check out that data. Exporting the results of a query to CSV is a friendly way to share said results because most people will have a program on their computer that can read a CSV file.

For example, exporting all your pokemon to /tmp/pokemon_dump.csv can be accomplished with:

copy (select * from pokemons) to '/tmp/pokemon_dump.csv' csv;

Because we are grabbing the entire table, we can just specify the table name instead of using a subquery:

copy pokemons to '/tmp/pokemon_dump.csv' csv;

Include the column names as headers to the CSV file with the header keyword:

copy (select * from pokemons) to '/tmp/pokemon_dump.csv' csv header;

source

Use A psqlrc File For Common Settings

There are a handful of settings that I inevitably turn on or configure each time I open up a psql session. I can save myself a little time and sanity by configuring these things in a .psqlrc dotfile that is located in my home directory. This will ensure my psql session is configured just how I like it each time I launch it. Here is what my ~/.psqlrc file currently looks like:

\x auto
\timing
\pset null 'Ø'

Reverse A Group Of Lines

The following command can be used to reverse the order of all lines in a file by doing a global move on all lines that match the beginning of line character starting at the theoretical 0th character:

:g/^/m 0

Reversing a range of lines is a little more work. Just as the previous example needs to be anchored against the 0th character, a specific range of lines needs to be anchored at the line just before the range. Thus reversing the lines 5 to 10 requires being anchored at line 4, like so:

:4,10g/^/m 4

See :h 12.4 for more details on how this works.

source

Create A Composite Primary Key

The unique identifier for a given row in a table is the primary key. Generally, a row can be uniquely identified by a single data point (such as an id), so the primary key is simply that single data point. In some cases, your data can be more appropriately uniquely identified by multiple values. This is where composite primary keys can lend a hand. Consider an example plane_tickets table where each ticket can be uniquely identified by the passenger and flight it is associated with:

create table plane_tickets (
  passenger_id integer references passengers not null,
  flight_id integer references flights not null,
  confirmation_number varchar(6) not null,
  seat_assignment varchar not null,
  primary key (passenger_id, flight_id)
);

Truncate Tables With Dependents

In Truncate All Rows, I talked about how postgres's truncate can be used to quickly delete all rows in a table. In practice this alone won't be very useful though, because tables usually have other tables that depend on them via foreign keys. If you have tables A and B where B has a foreign key referencing A, then trying to truncate A will result in something like this:

> truncate A;
ERROR:  cannot truncate a table referenced in a foreign key constraint

Fortunately, truncate has some tricks up its sleeve.

If you know two tables are tied together via a foreign key constraint, you can just truncate both of them at once:

> truncate A, B;
TRUNCATE TABLE;

If many tables are tied together in this way and you are looking to throw all of it out, then a simpler approach is to cascade the truncation:

> truncate A cascade;
NOTICE:  truncate cascades to table "B"
TRUNCATE TABLE

Use these with care and potentially within transactions because your data will go bye bye.

h/t Dillon Hafer and Jack Christensen

Truncate All Rows

Given a postgres database, if you want to delete all rows in a table, you can use the DELETE query without any conditions.

> delete from pokemons;
DELETE 151

Though DELETE can do the job, if you really are deleting all rows to clear out a table, you are better off using TRUNCATE. A TRUNCATE query will be faster than a DELETE query because it will just delete the rows without scanning them as it goes.

> truncate pokemons;
TRUNCATE TABLE

source

Check Ubuntu Version

Are you on Ubuntu? Want to know what version (release) of Ubuntu you are using?

Run the following to find out:

$ lsb_release -r

Beginning And End Of Previous Change

You can jump to the beginning of the previous change with the [ mark by hitting '[ from normal mode. Similarly, you can jump to the end of the previous change with the ] mark by hitting '].

Text that was just pasted is also considered a change. Thus, hitting '[ and '] will jump to the beginning and end, respectively, of the text that was just pasted into the buffer.

See :h '[ and :h '] for more details.

Center The Cursor

If you've moved the cursor to a particular line towards the top or bottom of the screen, you may want to center the screen on that line. This can be achieved by hitting zz. It is a quick way to center the cursor and ensure that you have an equal amount of context on either side of the line of interest.

Take care to not mistake this for ZZ which will save and quit the buffer.

See :h zz and :h z. for more details.

h/t Chris Erin

Insert Just The Defaults

If you are constructing an INSERT statement for a table whose required columns all have default values, you may just want to use the defaults. In this situation, you can break away from the standard:

> insert into table_name (column1, column2) values (value1, value2);

Instead, simply tell Postgres that you want it to use the default values:

> insert into table_name default values;

Jump To The Next Misspelling

If spelling is turned on (:set spell), you can jump back and forth between words that are misspelled. To jump to the next misspelling, hit ]s. To jump to the previous misspelling, hit [s.

See :h ]s and :h [s for more details.

Add Custom Dictionary Words

When editing a file with spell turned on, you may find vim highlighting some of your content in red. This red highlighting indicates a misspelling. Sure, these words technically aren't going to show up in something like the Merriam-Webster dictionary, but as far as you are concerned, they are words. They are part of your internal, shared language. The word admin is a great example. Why not just tell vim once and for all that such words are valid.

You can do just that by moving your cursor over the misspelled word and hitting zg. That will add it to the spellfile, a list of words, which vim includes in its spell checking. This means vim will no longer highlight that word red.

Delete Every Other Line

You can delete every other line in the current buffer using the following command.

There is a fairly elegant way in vim to delete every other line in the current buffer. Why would you want to do that? I don't know. Nevertheless, here it is:

:g/^/+d

This will essentially delete all even numbered lines. If you'd like to delete all odd numbered lines, delete the first line in the file (ggdd) and then run the same command as above.

This syntax is a bit awkward, so you may be better off going straight for a macro (e.g. qqjddq5@q or qqddjq5@q).

source

Generate A UUID In PostgreSQL

Postgres has support for universally unique identifiers (UUIDs) as a column data type via uuid. If you have a UUID column, you may need to generate a UUID. This requires the uuid-ossp module. This module provides a number of functions for generating UUIDs including the uuid_generate_v4() function which bases the UUID entirely off random numbers.

> create extension "uuid-ossp";
CREATE EXTENSION
> select uuid_generate_v4();
           uuid_generate_v4
--------------------------------------
 a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11

See the postgres docs for more details on UUID generation functions.

Pane Killer

In tmux, the current pane can be killed (closed) using the following key binding:

<prefix>x

You will be prompted to confirm with either y or n.

If there is only one pane in the current window, then the window will be killed along with the pane.

Navigating By Blank Lines

Use vim to open a file full of code (or text) that has some blank lines. Move the cursor to the middle of the file. Then start hitting { or }. You'll see that the cursor jumps from blank line to blank line.

Use { to jump to the closest blank line behind the cursor. Use } to jump to the closest blank line ahead of the cursor.

This may not seem like the most practical or obvious way to navigate, but it can help move you around a bit quicker than just tapping k and j.

Delete Lines That Match A Pattern

The :g command can be used to execute an Ex command over the entire buffer for all lines that match a given pattern. By choosing d (delete) as the Ex command, all lines that match the given pattern will be deleted. For instance, if I want to remove all lines that contain binding.pry, I can execute the following command:

:g/binding\.pry/d

See :h :g for more details.

h/t Chris Erin

Untrack A File Without Deleting It

Generally when I invoke git rm <filename>, I do so with the intention of removing a file from the project entirely. git-rm does exactly that, removing the file both from the index and from the working tree.

If you want to untrack a file (remove it from the index), but still have it available locally (in the working tree), then you are going to want to use the --cached flag.

$ git rm --cached <filename>

If you do this, you may also consider adding that file to the .gitignore file.

source

Running Out Of inode Space

Unix systems have two types of storage limitations. The first, and more common, is a limitation on physical storage used for storing the contents of files. The second is a limitation on inode space which represents file location and other data.

Though it is uncommon, it is possible to run out of inode space before running out of disk space (run df and df -i to see the levels of each). When this happens, the system will complain that there is No space left on device. Both inode space and disk space are needed to create a new file.

How can this happen? If lots of directories with lots of empty, small, or duplicate files are being created, then the inode space can be used up disproportionately to the amount of respective disk space. You'll need to clean up some of those files before you can continue.

Sources: this and this

Searching For Hex Digits

If you want to find sequences of hex digits (A-F, a-f and 0-9) in a search, you can hack together something like:

/[A-Fa-f0-9]\+

This is a bit verbose, though. Vim has a number of built in character classes that can be referenced in searches and substitutions. For hex digits, there is \x. Using this, the search above can be achieved with:

/\x\+

See :h \x for more details and other character classes.

SSH With A Specific Key

When you SSH into another machine using public key authentication, the key pair from either ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, or ~/.ssh/id_rsa is used by default. This is generally what you want. But what if the target server is expecting to identify you with a different SSH key pair?

The -i option can be used with ssh to specify a different identity file when the default isn't what you want.

Check The Syntax Of nginx Files

The syntax of nginx configuration files can be a bit finicky. On top of that, some nginx server commands can fail silently. Get more confidence by using the following command to check for syntax errors in those files:

$ [sudo] nginx -t

If there is an error, you might see something like this:

$ sudo nginx -t
nginx: [emerg] unexpected ";" in /etc/nginx/nginx.conf:16
nginx: configuration file /etc/nginx/nginx.conf test failed

If all looks good, then you'll see this:

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Clean Up Old Remote Tracking References

After working on a Git-versioned project for a while, you may find that there are a bunch of references to remote branches in your local repository. You know those branches definitely don't exist on the remote server and you've removed the local branches, but you still have references to them lying around. You can reconcile this discrepancy with one command:

$ git fetch origin --prune

This will prune all those non-existent remote tracking references which is sure to clean up your git log (git log --graph).

source

Colorful Output With MiniTest

Ruby's MiniTest is a minimal testing framework that you can easily drop-in to any Ruby project. For those used to using RSpec with it's fancy red/green output, MiniTest can be a little disappointing. It prints boring, uncolored text to the screen that lacks visual feedback. Fortunately, red and green coloring can be added with minitest/reporters.

Update your Gemfile:

gem 'minitest-reporters'

Then require and configure minitest-reporters in your testing setup file (e.g. test/test_helper.rb):

require 'minitest/reporters'
Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(:color => true)]

You can now enjoy that Red, Green, Refactor cycle.

Jump To Matching Pair

If you are dealing with code or data that contains parentheses or brackets that are hard to follow, you can easily jump between them with %.

For example, if you move over a [ and hit %, Vim will jump your cursor to the matching ]. Hit % one more time and it will jump back.

See :h % for more details.

h/t Jake Worth

Amend Commits With Fugitive

Let's assume you are using fugitive for Git integration with Vim. You've made a commit that you want to amend. First, stage any changes that should be included in the amend with :Gstatus or :Ge:. Then hit ca to open up the commit window for amending. Save and quit when you are finished.

Want to view the aggregate changes? Open the commit window for amending in verbose mode with cva.

See the vim-fugitive docs for more details.

File Type Info With File

Use the file utility to determine the type of a file:

$ file todo.md
todo.md: ASCII English text

$ file Hello.java
Hello.java: ASCII C++ program text

$ file Hello.class
Hello.class: compiled Java class data, version 52.0

The Hello.java file isn't exactly a C++ program, but close enough.

Swapping Split Windows

Consider a scenario where you have a vim window that has been split horizontally into two viewports. You'd prefer the top one to be on bottom and the bottom one to be on top. You want to swap them.

If you are currently focused on the top viewport, then tell vim to move that viewport down with CTRL-w J. As you might guess, moving the bottom viewport up can be done with CTRL-w K. J and K mean down and up in other contexts; vim is consistent with their meaning here.

Viewports of a vertical split can be swapped in the same sort of way. Use CTRL-w L to move the left viewport to the right. Use CTRL-w H to move the right viewport to the left.

Getting A Slice Of An Array In PostgreSQL

Postgres has a very natural syntax for grabbing a slice of an array. You simply add brackets after the array declaring the lower and upper bounds of the slice separated by a colon.

> select (array[4,5,6,7,8,9])[2:4];
  array
---------
 {5,6,7}

Notice that the bounds are inclusive, the array index is 1-based, and the array declaration above needs to be wrapped in parentheses in order to not trip up the array slice syntax.

You can also select rectangular slices from two dimensional arrays like so:

> select (array[[1,2,3],[4,5,6],[7,8,9]])[2:3][1:2];
     array
---------------
 {{4,5},{7,8}}

Defining Arrays In PostgreSQL

In postgres, an array can be defined using the array syntax like so:

> select array['a','b','c'];
  array
---------
 {a,b,c}

If you are inserting into an existing array column, you can use the array literal syntax.

> create temp table favorite_numbers(numbers integer[]);
CREATE TABLE
> insert into favorite_numbers values( '{7,3,9}' );
INSERT 0 1
> select numbers[2] from favorite_numbers;
 numbers
---------
       3

Postgres also supports two-dimensional arrays.

select array[[1,2,3],[4,5,6],[7,8,9]] telephone;
         telephone
---------------------------
 {{1,2,3},{4,5,6},{7,8,9}}

Set Maximum Heap Size In Lein

For lein-based projects, the maximum heap size can be set by including the -Xmx option in the jvm-opts portion of the project.clj file. For instance, to set the maximum JVM heap size to 2 gigabytes, include:

  :jvm-opts ["-Xmx2g"]

in your project.clj file.

Caching Credentials

When public key authentication isn't an option, you may find yourself typing your password over and over when pushing to and pulling from a remote git repository. This can get tedious. You can get around it by configuring git to cache your credentials. Add the following lines to the .git/config file of the particular project.

[credential]
    helper = cache --timeout=300

This will tell git to cache your credentials for 5 minutes. Use a much larger number of seconds (e.g. 604800) to cache for longer.

Alternatively, you can execute the command from the command line like so:

$ git config credential.helper 'cache --timeout=300'

source

Autosave False On ActiveRecord Associations

A relationship between two ActiveRecord models can be established with a has_one or has_many association. This relationship has some implications. By default, saving a record will also save the associated records that have since been built. Consider this example of users that have many posts.

> u = User.first
#=> #<User ...>
> u.posts
#=> []
> u.posts.build(title: "Some Title", content: "This is a post")
#=> #<Post ...>
> u.save
#=> true
> u.posts(reload: true)
#=> [#<Post ...>]

When the user is saved, the associated post that was built for that user also gets saved to the database.

If the association is instead defined with the autosave option set to false, then saving a record will not cause associated records to also be saved. The associated records will need to be saved explicitly. Consider the same example from above, but with has_many posts, autosave: false.

> u = User.first
#=> #<User ...>
> u.posts
#=> []
> u.posts.build(title: "Some Title", content: "This is a post")
#=> #<Post ...>
> u.save
#=> true
> u.posts(reload: true)
#=> []

The post wasn't saved with the user and it wasn't saved explicitly, so it isn't persisted to the database.

Replace The Current Process With An External Cmd

Go's syscall.Exec function can be used to execute an external program. Instead of forking a child process though, it runs the external command in place of the current process. You need to give the function three pieces of information: the location of the binary, the pieces of the command to be executed, and relevant environment variables. Here is a simple example.

package main

import "fmt"
import "os"
import "syscall"

func main() {
    // get the system's environment variables
    environment := os.Environ()

    // get a slice of the pieces of the command
    command := []string{"tmux", "new-session", "-s", "burrito"}

    err := syscall.Exec("/usr/local/bin/tmux", command, environment)
    if err != nil {
        fmt.Printf("%v", err)
    }
}

When this program is executed, it will replace itself with a new tmux session named burrito.

Construct A Constant From A String

Ruby's Module.const_get can be used to look for and retrieve the constant for a given name.

This can be used to construct a class name

> Object.const_get("Math")
#=> Math
> Object.const_get("Math")::PI
#=> 3.141592653589793

It can also be used to reference a constant

> Object.const_get("Math::PI")
#=> 3.141592653589793

You can even be more specific if you'd like

> Math.const_get("PI")
#=> 3.141592653589793

Symbols are valid as well

> Math.const_get(:PI)
#=> 3.141592653589793

Grab A Single File From A Stash

In git, you can reference a commit SHA or branch to checkout differing versions of files.

$ git checkout d3d2e38 -- README.md

In the same way, you can snag the version of a file as it existed in a stash. Just reference the relevant stash.

$ git checkout stash@{1} -- README.md

source

List Postgres Database Users

Within psql, type \du to list all the users for a database and their respective permissions.

> \du
                              List of roles
 Role name  |                   Attributes                   | Member of
------------+------------------------------------------------+-----------
 jbranchaud | Superuser, Create role, Create DB, Replication | {}
 sampleuser | Create DB                                      | {}

Default Screenshot Location On Mac

By default, Mac saves all screenshots to the desktop. If you'd like screenshots to be dumped somewhere else, you have to configure it manually from the command line. For instance, if you'd like your screenshots to be saved in the ~/screenshots directory, then enter the following commands:

$ mkdir ~/screenshots
$ defaults write com.apple.screencapture location ~/screenshots
$ killall SystemUIServer

source

Repeating Characters

It's not common to need to type 39 space characters in a row, but when the moment arises, you don't want to be caught hitting the space bar 39 times. Vim makes it easy. From normal mode, type the number, then i, and then the character to be repeated followed by an escape.

For instance, for 39 spaces, hit:

39i <esc>

or for 80 dashes, hit:

80i-<esc>

Replace The Current Process With An External Cmd

Ruby's Kernel#exec method can be used to run an external command. What differentiates it from executing commands with the likes of back ticks or %x[] is that instead of forking a child process, it replaces the current process.

For instance, the following ruby script, when executed, will replace itself with an irb session.

Kernel.exec('irb')

The external command will even benefit from the existing environment. For example, if I set the following environment variable

$ export GREETING=hello

and then execute a file containing

Kernel.exec('echo $GREETING')

I can expect to see hello printed to stdout.

Deleting Directories Of Files From netrw

In netrw, you can delete files and directories by navigating over the target of deletion and hitting D.

By default, netrw will use rmdir when deleting directories. This means that if a directory has files in it, then it won't be deleted. rmdir rightly gives an error when the target directory isn't empty.

Not to worry though, netrw can be configured to use rm -r instead of rmdir when deleting directories.

:let g:netrw_localrmdir='rm -r'

source

Determine The Hash Id For A Blob

Git's hash-object command can be used to determine what hash id will be used by git when creating a blob in its internal file system.

$ echo 'Hello, world!' > hola
$ git hash-object hola
af5626b4a114abcb82d63db7c8082c3c4756e51b

When a commit happens, git will generate this digest (hash id) based on the contents of the file. The name and location of the file don't matter, just the contents. This is the magic of git. Anytime git needs to store a blob, it can quickly match against the hash id in order to avoid storing duplicate blobs.

Try it on your own machine, you don't even need to initialize a git repository to use git hash-object.

source

Format Long Lines To Text Width

Vim allows you to set the maximum width for text per line in a buffer with the textwidth setting. For example, you can set the maximum text width to 80 characters like so:

:set textwidth=80

With this set, vim will automatically break on whitespace whenever you hit 80 characters. However, there are two places where this doesn't quite pan out. You will see this as soon as you open a file with lines of text that exceed 80 characters and when you paste long lines of text into your buffer. You can quickly remedy this with gw.

Make a visual selection of the lines that need formatting and then hit gw. All the lines should then we truncated to 80 or less characters.

See :h gw and :h gq for more details.

Absolute And Relative Line Numbers

By default, vim uses absolute line numbering. This can be turned off with set nonumber or more concisely set nonu. Turn it back on with set nu. Get more details at :h number.

Vim also supports relative line numbers. If you'd rather use relative line numbers, first turn off absolute line numbers (set nonu) and then turn on relative line numbers with set relativenumber. Shave off some characters with set rnu. As you might expect, you can turn off relative numbering with set nornu.

See :h relativenumber for more details.

Invoking Rake Tasks Multiple Times

I have a rake task, build, that builds a single record for development purposes. I want a supplemental rake task, build:all, that builds a bunch of different records. To keep things dry, build:all should just invoke build a number of times.

namespace :build do
  task :all do
    predefined_list.each do |data|
      Rake::Task["build"].invoke(data)
    end
  end
end

This doesn't work though. No matter how many items are in the list, the build task only seems to get run once. This is because by default tasks can only be invoked once in a given context. To get around this, the task needs to be reenabled after each invocation.

namespace :build do
  task :all do
    predefined_list.each do |data|
      Rake::Task["build"].invoke(data)
      Rake::Task["build"].reenable
    end
  end
end

Last Raised Exception In The Call Stack

In Ruby, the $! global variable contains the last exception that was raised in the current call stack. This makes it trivial to check what error is being rescued even if it hasn't been captured in a local variable.

class MyError < StandardError; end

def do_stuff
  raise MyError
rescue
  puts "rescuing #{$!}"
end

do_stuff
#=> rescuing MyError

Case-Aware Substitution With vim-abolish

Substitution in vim is, by default, case-sensitive. Adding the i s-flag makes it case-insensitive. vim-abolish, on the other hand, lets you perform a case-insensitive substitution that preserves three case variants (foo, Foo, and FOO). Substitution with vim-abolish can be performed with Subvert or S.

For instance, :%S/blog/article/g will turn

blog Blog bLOg BLOG

into

article Article bLOg ARTICLE

Install vim-abolish and see :h Subvert for more details.

Case-Insensitive Substitution

Use the i s-flag to perform a case-insensitive substitution (search and replace).

For instance, :%s/blog/article/gi will turn

blog bLOg BLOG Blog

into

article article article article

See :h s_flags for more details.

Create A New Directory In netrw

With netrw open (try vi .), navigate to the parent directory you want to create a new directory in and then hit d. Type the name of the new directory in the provided prompt and then hit enter.

Inspired by Micah Woods' TIL from earlier today.

Alternate Files With vim-rails

If you are doing a good job of testing all the code you write in a rails project, then most of your code files should be paired with test (or spec) files. You can think of these as alternate files. The alternate file of user.rb is user_spec.rb and vice versa.

The vim-rails plugin makes it easy to jump back and forth between alternate files. Enter :A and you will go to the alternate file of the current file. This makes a common navigation path for rails projects all the more efficient.

Hash Slicing

Rails' ActiveSupport adds #slice and #slice! to the Hash class. The interface of these two methods seems a little inconsistent though.

> {a: 1, b: 2, c: 3}.slice(:a)
=> {:a=>1}

The #slice method returns what is being sliced.

> {a: 1, b: 2, c: 3}.slice!(:a)
=> {:b=>2, :c=>3}

The #slice! method, on the other hand, returns what is being excluded.

Securely Remove Files

If you really want to make sure you have wiped a file from your hard drive, you are going to want to use srm instead of rm. The man page for srm gives the following description:

srm removes each specified file by overwriting, renaming, and truncating it before unlinking. This prevents other people from undeleting or recovering any information about the file from the command line.

h/t Dillon Hafer

Filter Lines Through An External Program

Vim allows you to filter lines from your current buffer through an external program. For instance, if you have some ugly looking json that you'd like to format in a readable way, you might want to filter it through an external json pretty printer program.

To filter the entire file through an external program, use

:%!! <external-program>

Or you can make a visual selection and just filter that

:'<,'>!! <external-program>

See :h !! for more details.

Global Substitution On The Previous Command

Let's say we just executed the following command:

$ grep 'foo' foo.md

It gave us the information we were looking for and now we want to execute a similar command to find the occurrences of bar in bar.md. The ^ trick won't quite work here.

$ ^foo^bar<tab>
$ grep 'bar' foo.md

What we need is a global replace of foo in our previous command. The !! command can help when we sprinkle in some sed-like syntax.

$ !!gs/foo/bar<tab>
$ grep 'bar' bar.md

For a short command like this, we haven't gained much. However, for large commands that span the length of the terminal, this can definitely save us a little trouble.

Rake Only Lists Tasks With Descriptions

Rake describes the -T flag as

Display the tasks (matching optional PATTERN) with descriptions, then exit.

And rake -T does just exactly that. It lists all the tasks with descriptions. Any rake task that you define without a desc will not be included.

Consider the following rake task definitions

desc 'foobar does this and that'
task :foobar do
  puts 'this and that'
end

task :foobaz do
  puts 'not so much'
end

This is what I get when listing the rake tasks filtered by foo

$ rake -T foo
rake foobar  # foobar does this and that

The foobar task (which has a description) is listed, but foobaz is not.

A hack of sorts to get around this is to use the -P flag which will end up listing all tasks even if they do not have a description (rake -P | grep 'foo').

Evaluate One Liners With lein-exec

You can install the lein-exec plugin and then use it to evaluate one liner bits of code with the -e flag.

$ lein exec -e '(println "foo" (+ 20 30))'
foo 50

Passing Arguments To A Rake Task

You can create a rake task that takes arguments by including an array of named arguments in the task declaration.

task :greeting, [:name] do |task, args|
  puts "Hello, #{args.name}!"
end

You can then pass an argument to that task when invoking it.

$ rake greeting[World]
Hello, World!

source

Do Not Overwrite Existing Files

When using the cp command to copy files, you can use the -n flag to make sure that you do not overwrite existing files.

h/t Dillon Hafer

Next Modified Buffer

After working for a while on a feature that involves looking at a number of files, I end up with a decent buffer list. I will have inevitably edited a few of those files and occasionally I'll inadvertently leave one of the buffers modified. Instead of opening the buffer list (:ls), finding the modified buffer, and navigating to it, I can just jump straight to it. I can do this with :bmodified or just :bm. This jumps straight to the next modified buffer. If there is no modified buffer, it tells me No modified buffer found.

See :h bmodified for more details.

`undef_method` And The Inheritance Hierarchy

As the docs state, Ruby's undef_method

prevents the current class from responding to calls to the named method.

This means you can do some weird things to the inheritance hierarchy. I'll use the following code example to illustrate.

class Phone
  def ring
    puts 'brrrrriiing'
  end
end

class Smartphone < Phone
  def ring
    puts 'boop beep boop'
  end
end

class Iphone < Smartphone
end

smartphone = Smartphone.new
iphone = Iphone.new

smartphone.ring
#=> boop beep boop
iphone.ring
#=> boop beep boop

Everything works as expect. Now, I'll use undef_method.

class Smartphone
  undef_method(:ring)
end

smartphone.ring
#=> NoMethodError: undefined method `ring' for #<Smartphone:0x007fd0a20b7960>
iphone.ring
#=> NoMethodError: undefined method `ring' for #<Iphone:0x007fd0a20b7938>

Not only have instances of Smartphone been prevented from responding to ring, but any subclasses of Smartphone that call ring will get tripped up when traversing the inheritance hierarchy in search of a definition of ring.

Passing Arbitrary Methods As Blocks

Use Object#method to create a callable Method object that can be passed to methods that yield to a block.

def inc(x)
  x + 1
end

[1,2,3].map(&method(:inc))
#=> [2,3,4]

Excluding Files Locally

Excluding (read: ignoring) files that should not be tracked is generally done by listing such files in a tracked .gitignore file. Though it doesn't make sense to list all kinds of excluded files here. For files that you'd like to exclude that are temporary or are specific to your local environment, there is another option. These files can be added to the .git/info/exclude file as a way of ignoring them locally.

Add specific files or patterns as needed to that file and then save it. Relevant files will no longer show up as untracked files when you git status.

h/t Dillon Hafer

Listing Local Variables

In Ruby 2.2, the binding object gives us access to a method #local_variables which returns the symbol names of the binding's local variables. We can see this in action with

def square(x)
  puts binding.local_variables.inspect
  x.times do |a|
    puts binding.local_variables.inspect
  end
  z = x * x
  puts binding.local_variables.inspect
  z
end
square(2)

which results in

[:x, :z]
[:a, :x, :z]
[:a, :x, :z]
[:x, :z]
=> 4

source

Ignore Changes To A Tracked File

Files that should never be tracked are listed in your .gitignore file. But what about if you want to ignore some local changes to a tracked file?

You can tell git to assume the file is unchanged

$ git update-index --assume-unchanged <some-file>

Reversing the process can be done with the --no-assume-unchanged flag.

source

List All Versions Of A Function

Within psql you can use \df to list a postgres function with a given name

> \df now
                              List of functions
   Schema   | Name |     Result data type     | Argument data types |  Type
------------+------+--------------------------+---------------------+--------
 pg_catalog | now  | timestamp with time zone |                     | normal
(1 row)

When a function has multiple definitions across a number of types, \df will list all versions of that function

> \df generate_series
List of functions
-[ RECORD 1 ]-------+-------------------------------------------------------------------
Schema              | pg_catalog
Name                | generate_series
Result data type    | SETOF bigint
Argument data types | bigint, bigint
Type                | normal
-[ RECORD 2 ]-------+-------------------------------------------------------------------
Schema              | pg_catalog
Name                | generate_series
Result data type    | SETOF bigint
Argument data types | bigint, bigint, bigint
Type                | normal
-[ RECORD 3 ]-------+-------------------------------------------------------------------
Schema              | pg_catalog
Name                | generate_series
Result data type    | SETOF integer
Argument data types | integer, integer
Type                | normal
-[ RECORD 4 ]-------+-------------------------------------------------------------------
Schema              | pg_catalog
Name                | generate_series
Result data type    | SETOF integer
Argument data types | integer, integer, integer
Type                | normal
-[ RECORD 5 ]-------+-------------------------------------------------------------------
...

List All The Say Voices

The say command can be a fun party trick.

$ say Get ready for the bass to drop

Your friends will be even more impressed when you use some of the alternate voices.

$ say -v Daniel Would you like a cup of tea?

To see all the alternate voices available, type the following

$ say -v '?'

source

Ignore Poltergeist JavaScript Errors

Poltergeist with PhantomJS (<2.0) does not support JavaScript's bind() method. This means that when executing an integration test that exercises JavaScript with the bind() method, an error will occur. If you cannot simply upgrade to a version of PhantomJS that supports bind(), then what can you do?

Ignore the error!

This can be achieved by placing the following rescue block in the appropriate place.

rescue Capybara::Poltergeist::JavascriptError

Use this in moderation. You want to make sure you don't ignore actual JavaScript errors.

source

Select Value For SQL Counts

If you are like me and prefer writing raw SQL over the Arel DSL for counting stuff in your database, then the select_value method will come in handy. Write a command similar to the following with a type cast to get the count of whatever.

> sql = 'select count(*) from posts where published_at is not null'
=> "select count(*) from posts where published_at is not null"
> ActiveRecord::Base.connection.select_value(sql).to_i
   (0.6ms)  select count(*) from posts where published_at is not null
=> 42

Writing raw SQL for a simple query like this hardly seems like a win. However when a count query starts to involve joins or other fanciness, I find it much clearer to reason about the raw SQL.

Special Math Operators

Postgres has all the mathematical operators you might expect in any programming language (e.g. +,-,*,/,%). It also has a few extras that you might not be expecting.

Factorial Operator:

> select 5!;
 ?column?
----------
      120
(1 row)

Square Root Operator:

> select |/81;
 ?column?
----------
        9
(1 row)

Absolute Value Operator:

> select @ -23.4;
 ?column?
----------
     23.4
(1 row)

Cycle Through tmux Layouts

Arranging a series of split windows in tmux can take some time. Once those splits windows are arranged, it is difficult to set them up in a new way. There is a way of cycling through layouts that might be able to help though. Hit <prefix><space> over and over to cycle through the layouts until you find the arrangement that you want.

source

Edges Of The Selection

When you make a visual selection, Vim stores the position of the first character of the selection in the < mark and the position of the last character of the selection in the > mark.

Thus moving to the edges of your previous selection is easy. To move to the beginning of the selection, press

`<

To move to the end, press

`>

Send A Command To psql

You can send a command to psql to be executed by using the -c flag

$ psql -c "select 'Hello, World!';"
   ?column?
---------------
 Hello, World!
(1 row)

Specify a particular database as needed

$ psql blog_prod -c 'select count(*) from posts;'
 count 
-------
     8 
(1 row)

h/t Jack Christensen

List Of Plugins

Get a list of all your plugins (and other sourced scripts) with

:scriptnames

See :h scriptnames for more details.

Checking The Type Of A Value

The pg_typeof() function allows you to determine the data type of anything in Postgres.

> select pg_typeof(1);
 pg_typeof
-----------
 integer
(1 row)

> select pg_typeof(true);
 pg_typeof
-----------
 boolean
(1 row)

If you try it on an arbitrary string, it is unable to disambiguate which string type (e.g. text vs varchar).

> select pg_typeof('hello');
 pg_typeof
-----------
 unknown
(1 row)

You just have to be a bit more specific.

> select pg_typeof('hello'::varchar);
     pg_typeof
-------------------
 character varying
(1 row)

source

Create A Named tmux Session

When creating a new tmux session

$ tmux new

a default name of 0 will be given to the session.

If you'd like to give your session a name with a bit more meaning, use the -s flag

$ tmux new -s burrito

source

Question Mark Operator

Ruby has a question mark (?) operator that works like so

> ?a
=> "a"
> ?\s
=> " "
> ??
=> "?"
> ?a + ?b + ?c
=> "abc"

It essentially creates single character strings. At least in Ruby 1.9+ it does. In versions of Ruby before 1.9, the ? operator could be used to get the ascii character code of the operand character.

h/t Josh Davey

source

Intervals Of Time By Week

It is pretty common to use hours or days when creating a Postgres interval. However, intervals can also be created in week-sized chunks

> select '2 weeks'::interval;
 interval
----------
 14 days
(1 row)

> select make_interval(0,0,7,0,0,0,0);
 make_interval
---------------
 49 days
(1 row)

Use Argument Indexes

In Postgres, each of the arguments you specify in a select statement has a 1-based index tied to it. You can use these indexes in the order by and group by parts of the statement.

Instead of writing

select id, updated_at from posts order by updated_at;

you can write

select id, updated_at from posts order by 2;

If you want to group by a table's type and then order by the counts from highest to lowest, you can do the following

select type, count(*) from transaction group by 1 order by 2 desc;

Percent Notation

Ruby has many uses for the % character. One of the more obscure uses is as a notion for custom delimited strings. Use the percent notation with a non-alphanumeric character to surround a string.

> %=Jurassic Park=
=> "Jurassic Park"
> % Ghostbusters 
=> "Ghostbusters"

It even works with balanced characters

> %(The Goonies)
=> "The Goonies"

This is useful for defining a string that has both types of quotes

> %[That'll be the "day"]
=> "That'll be the \"day\""

It's also useful for creating horribly obfuscated code

> %=what===%?what?
=> true

h/t Josh Davey

Temporary Tables

Create a temporary table in Postgres like so

create temp table posts (
    ...
);

This table (and its data) will only last for the duration of the session. It is created on a schema specific to temporary tables. It is also worth noting that it won't be autovacuumed, so this must be done manually as necessary.

Fizzbuzz With Common Table Expressions

In learning about CTEs (common table expressions) in postgres, I discovered that you can do some interesting and powerful things using the with recursive construct. The following solves the fizzbuzz problem for integers up to 100

with recursive fizzbuzz (num,val) as (
    select 0, ''
    union
    select (num + 1),
      case
      when (num + 1) % 15 = 0 then 'fizzbuzz'
      when (num + 1) % 5  = 0 then 'buzz'
      when (num + 1) % 3  = 0 then 'fizz'
      else (num + 1)::text
      end
    from fizzbuzz
    where num < 100
)
select val from fizzbuzz where num > 0;

Check out With Queries (Common Table Expressions) for more details on CTEs.

Default Schema

Schemas can be used to organize tables within a database. In postgres, we can see all the schemas our database has like so

> select schema_name from information_schema.schemata;
    schema_name
--------------------
 pg_toast
 pg_temp_1
 pg_toast_temp_1
 pg_catalog
 public
 information_schema
(6 rows)

When you create a new table, it will need to be placed under one of these schemas. So if we have a create table posts (...), how does postgres know what schema to put it under?

Postgres checks your search_path for a default.

> show search_path;
   search_path
-----------------
 "$user", public
(1 row)

From our first select statement, we see that there is no schema with my user name, so postgres uses public as the default schema.

If we set the search path to something that won't resolve to a schema name, postgres will complain

> set search_path = '$user';
SET
> create table posts (...);
ERROR:  no schema has been selected to create in

Repeat Yourself

Use the repeat command to repeat some other command.

You can repeat a command any number of times like so

$ repeat 5 say Hello World

List All Columns Of A Specific Type

In postgres, we can access information about all the columns in our database through the information_schema tables; in particular, the columns table. After connecting to a particular database, we can list all columns (across all our tables) of a specific type. We just need to know the schema of the tables we are interested in and the type that we want to track down.

My application's tables are under the public schema and I want to track down all timestamp columns. My query can look something like this

> select table_name, column_name, data_type from information_schema.columns where table_schema = 'public' and data_type = 'timestamp without time zone';
   table_name    | column_name |          data_type
-----------------+-------------+-----------------------------
 articles        | created_at  | timestamp without time zone
 articles        | updated_at  | timestamp without time zone
 users           | created_at  | timestamp without time zone
 users           | updated_at  | timestamp without time zone
(4 rows)

Alternatively, I could look for both timestamp and timestamptz with a query like this

> select table_name, column_name, data_type from information_schema.columns where table_schema = 'public' and data_type like '%timestamp%';

Temporarily Disable Triggers

In general, you are always going to want your triggers to fire. That's why they are there. Though special circumstances may arise where you need to temporarily disable them. In postgres, you can use

> set session_replication_role = 'replica';
SET

By changing the replication role from origin to replica you are essentially disabling all non-replica triggers across the database (for that session). When you are done, you can simply set the replication role back so that normal trigger behavior can resume

> set session_replication_role = 'origin';
SET

A more direct and fine-grained approach to disabling triggers is to use an alter table command that targets a specific trigger.

h/t Jack Christensen

Watch The Difference

The watch command is a simple way to repeatedly run a particular command. I'll sometimes use it to monitor the response from some endpoint. watch can make monitoring responses even easier when the -d flag is employed. This flag instructs watch to highlight the parts of the output that are different from the previous run of the command.

So if I run

$ watch -d curl -LIs localhost:3000

I can easily see if the http status of the request changes.

Limit Execution Time Of Statements

You can limit the amount of time that postgres will execute a statement by setting a hard timeout. By default the timeout is 0 (see show statement_timeout;) which means statements will be given as much time as they need.

If you do want to limit your statements, to say, 1 second, you can set the execution time like so

> set statement_timeout = '1s';
SET
> show statement_timeout;
 statement_timeout
-------------------
 1s
(1 row)

Any queries taking longer than 1 second will be aborted with the following message output

ERROR:  canceling statement due to statement timeout

Auto Expanded Display

By default, postgres has expanded display turned off. This means that results of a query are displayed horizontally. At times, the results of a query can be so wide that line wrapping occurs. This can make the results and their corresponding column names rather difficult to read. In these situations, it is preferable to turn on expanded display so that results are displayed vertically. The \x command can be used to toggle expanded display on and off.

Having to toggle expanded display on and off depending on the way a particular set of results is going to display can be a bit tedious. Fortunately, running \x auto will turn on auto expanded display. This means postgres will display the results normally when they fit and only switch to expanded display when it is necessary.

h/t Jack Christensen

Generate Series Of Numbers

Postgres has a generate_series function that can be used to, well, generate a series of something. The simplest way to use it is by giving it start and stop arguments

> select generate_series(1,5);
 generate_series 
-----------------
               1
               2
               3
               4
               5

The default step is 1, so if you want to count backwards, you need to specify a negative step

> select generate_series(5,1,-1);
 generate_series 
-----------------
               5
               4
               3
               2
               1

You can use a larger step value to, for instance, get only multiples of 3

> select generate_series(3,17,3);
 generate_series 
-----------------
               3
               6
               9
              12
              15

Trying this out with timestamps is left as an exercise for the reader.

Last Commit A File Appeared In

In my project, I have a README.md file that I haven't modified in a while. I'd like to take a look at the last commit that modified it. The git log command can be used here with few arguments to narrow it down.

$ git log -1 -- README.md
commit 6da76838549a43aa578604f8d0eee7f6dbf44168
Author: jbranchaud <jbranchaud@gmail.com>
Date:   Sun May 17 12:08:02 2015 -0500

    Add some documentation on configuring basic auth.

This same command will even work for files that have been deleted if you know the path and name of the file in question. For instance, I used to have an ideas.md file and I'd like to find the commit that removed it.

$ git log -1 -- docs/ideas.md
commit 0bb1d80ea8123dd12c305394e61ae27bdb706434
Author: jbranchaud <jbranchaud@gmail.com>
Date:   Sat May 16 14:53:57 2015 -0500

    Remove the ideas doc, it isn't needed anymore.

String Contains Another String

In postgres, you can check if a string contains another string using the position function.

> select position('One' in 'One Two Three');
 position
----------
        1

It returns the 1-based index of the first character of the first match of that substring.

> select position('Four' in 'One Two Three');
 position
----------
        0

If the substring doesn't appear within the string, then the result is 0.

Thus, you can determine if a string contains another string by checking if the value resulting from position is greater than 0.

Configure The Timezone

In postgres, running show timezone; will reveal the timezone for your connection. If you want to change the timezone for the duration of the connection, you can run something like

> set timezone='America/New_York';
SET
> show timezone;
 TimeZone
------------------
 America/New_York
(1 row)

Now, if you run a command such as select now();, the time will be in Eastern time.

h/t Jack Christensen

Reload The nginx Configuration

If you've modified or replaced the configuration file, nginx will not immediately start using the updated nginx configuration. Once a restart or reload signal is received by nginx, it will apply the changes. The reload signal

$ service nginx reload

tells nginx to reload the configuration. It will check the validity of the configuration file and then spawn new worker processes for the latest configuration. It then sends requests to shut down the old worker processes. This means that during a reload nginx is always up and processing requests.

source

Swap Occurrences Of Two Words

Imagine I have a file with foo and bar all over the place. The tables have turned and now I want all occurrences of foo to be bar and all occurrences of bar to be foo.

Reaching for a simple substitution won't work because after flipping all the occurrences of foo to bar. I will no longer be able to distinguish between the new bars and the bars that need to be flipped.

Abolish.vim enhances Vim's substitution capabilities making it easy to flip these strings in one relatively simple command.

:%S/{foo,bar}/{bar,foo}/g

Notice the uppercase S as well as the ordering of foo and bar in the before and after sequences.

Check If A Port Is In Use

The lsof command is used to list open files. This includes listing network connections. This means I can check if a particular port is in use and what process is using that port. For instance, I can check if my rails application is currently running on port 3000.

$ lsof -i TCP:3000
COMMAND   PID       USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    13821 jbranchaud   12u  IPv6 0xdf2e9fd346cc12b5      0t0  TCP localhost:hbci (LISTEN)
ruby    13821 jbranchaud   13u  IPv4 0xdf2e9fd33ca74d65      0t0  TCP localhost:hbci (LISTEN)

I can see that a ruby process (my rails app) is using port 3000. The PID and a number of other details are included.

See more details with man lsof.

h/t Mike Chau

Count Records By Type

If you have a table with some sort of type column on it, you can come up with a count of the records in that table by type. You just need to take advantage of group by:

> select type, count(*) from pokemon group by type;

  type   | count 
-----------------
 fire    |    10
 water   |     4
 plant   |     7
 psychic |     3
 rock    |    12

End Of The Word

Word-based movement can serve as a quick way to get around locally in Vim. I most often use w and b for this kind of movement. While w and b move me to the beginning of the next and previous word, respectively, I find that sometimes it would be more convenient if I were at the end of a word.

The e and ge commands serve this purpose well. e will move me to the end of the next word and ge will move me to the end of the previous word.

Retrieve An Object If It Exists

Rails' Active Support provides the blank? and present? convenience methods as extensions to many objects. It also extends the Object class by providing the presence method. This method returns the receiver if it is not blank, otherwise it returns nil.

Instead of doing

User.nickname.present? ? User.nickname : User.firstname

I can simply do

User.nickname.presence || User.firstname

Override The Initial Sequence Value

FactoryGirl sequences can be defined with an initial starting value

FactoryGirl.define do
  sequence :email, 1000 do |n|
    "person#{n}@example.com"
  end
end

thus:

> FactoryGirl.generate :email
=> "person1000@example.com"
> FactoryGirl.generate :email
=> "person1001@example.com"

List All tmux Key Bindings

There are a couple ways to list all the tmux key bindings. If you are not currently in a tmux session, you can still access the list from the terminal with

$ tmux list-keys

If you are currently in a tmux session, then you can take advantage of the tmux environment by either using

<prefix>:list-keys

or

<prefix>?

Any of these will bring up a list of all key bindings available to you within a tmux session on your machine.

Extracting Nested JSON Data

If you are storing nested JSON data in a postgres JSON column, you are likely going to find yourself in a situation where you need to access some of those nested values in your database code. For instance, you may need to get at the license number in this JSON column

  owner
--------------------------------------------------------------------------------
'{ "name": "Jason Borne", "license": { "number": "T1234F5G6", "state": "MA" } }'

Unfortunately, the -> operator isn't going to do the trick. You need the json_extract_path function

> select json_extract_path(owner, 'license', 'number') from some_table;

 json_extract_path
-------------------
   'T1234F5G6'

Read more about JSON Functions and Operators.

Set Your Color Scheme

Vim ships with a number of standard color schemes for both light and dark backgrounds. You can also find and install many others. To set your color scheme, you can use the :colorscheme command. You can quickly see what color schemes are available by typing :colorscheme and then tabbing for completion. For instance, you can set the delek color scheme by entering

:colorscheme delek

See :h colorscheme for more details.

FactoryGirl Sequences

FactoryGirl sequences are often used inline for unique values such as emails:

factory :user do
  sequence(:email) { |n| "person#{n}@example.com" }
end

However, a sequence can be defined on its own

FactoryGirl.define do
  sequence :email do |n|
    "person#{n}@example.com"
  end
end

That means it can be invoked outside the context of a factory

> FactoryGirl.generate :email
=> "person1@example.com"
> FactoryGirl.generate :email
=> "person2@example.com"

Or it can be used as a shared sequence across multiple factories

factory :customer do
  ...
  email
end

factory :admin do
  ...
  email
end

Comparing Class Hierarchy Relationships

The comparator methods (<,>, etc.) can be useful for a lot of things. In Ruby, they can be used to compare classes in order to understand how they relate to one another on the class hierarchy.

# Fixnum is a subclass of Integer
> Fixnum < Integer
=> true
# Integer is not a subclass of Fixnum
> Integer < Fixnum
=> false
# Fixnum and String are not related to one another
> Fixnum < String
=> nil

The < operator will tell you if there is a subclass relationship. The > operator will tell you if there is an ancestor relationship. When nil results, it means the two classes do not have a direct relationship.

There are a few more of these types of operators on the Module class.

source

Toggling The Pager In PSQL

When the pager is enabled in psql, commands that produce larger output will be opened in a pager. The pager can be enabled within psql by running \pset pager on.

If you'd like to retain the output of commands, perhaps as reference for subsequent commands, you can turn the pager off. As you might expect, the pager can be disabled with \pset pager off.

source

Check Your Current Color Scheme

Vim ships with a number of different color schemes. There is also a plethora of color schemes built by the open source community. If you'd like to know what color scheme you are currently using, you can check with

:echo g:colors_name

So more details at both :h g:colors_name and :h colorscheme.

Incremental Searching

You can do a text-based search on the contents of your current buffer by hitting / and then beginning to type a pattern (including regex). The incsearch feature makes searching for text even easier. As you type your pattern, the first valid match will be located and highlighted. As you continue to type the pattern, it will continue to update the highlighted match. Incremental searching makes it easy to see when you've made a typo in your pattern. By default incsearch is turned off in Vim. You can enable it with :set incsearch.

See :h incsearch for more details.

Check The Status Of All Services

In a Linux environment, you can quickly check the status of a number of different services. By running [sudo] service --status-all, the status command will be invoked for all services under the /etc/init.d/ directory.

So, if you want to check the status of something like nginx or apache, just run service --status-all and find it in the list. The - symbol means it isn't running, the + symbol means it is up, and the ? symbol means that it cannot determine the status.

Wipe A Heroku Postgres Database

If you have some sort of non-production version of an application running on Heroku, you may encounter a time when you need to wipe your database and start fresh. For a rails project, it may be tempting to do heroku run rake db:drop db:setup. Heroku doesn't want you to accidentally do anything stupid, so it prevents you from running rake db:drop. Instead, you must send a more explicit command

$ heroku pg:reset DATABASE_URL

Heroku will ask you to confirm that you indeed want to wipe out the database and will then proceed.

For the curious reader, running heroku config will list the values of a number of variables including DATABASE_URL.

Throttling A Function Call

Imagine you have a JavaScript function that makes a request to your server. Perhaps it is sending user input from a textarea to be processed by the server. You may want to wrap this function in a keyboard event listener so that you are sure to react immediately to any user input. However, as the user starts typing away into this text area you may find that way to many requests are being fired off to the server. The request needs to be throttled.

You can roll your own approach to sufficiently intermittent server calls. Though, it turns out that underscore.js comes with two functions out of the box for this kind of behavior.

  • throttle will give you a function that wraps your function in a way that essentially rate-limits it to being called at most once every N milliseconds.

  • debounce, on the other hand, will give you a function that only calls your function once N milliseconds has passed since it was last called.

These are two subtly different approaches to making sure a function gets called, just not too often.

h/t Jake Worth

Saying Yes

Tired of being prompted for confirmation by command-line utilities? Wish you could blindly respond 'yes' to whatever it is they are bugging you about? The yes command is what you've been looking for.

$ yes | rm -r ~/some/dir

This will respond y as rm asks for confirmation on removing each and every file in that directory.

yes is just as good at saying no. Give it no as an argument and it will happily (and endlessly) print no.

$ yes no

h/t Chris Erin

Reclaiming The Entire Window in tmux

If you have attached to a tmux session whose dimensions are being constrained by another connection, you may find an L-shaped portion of your window filled with dots. tmux defers to the session with smaller dimensions. The easiest way to reclaim the entire window for your session is to attach to the session while forcing all other sessions to detach. The -d flag will help with that.

$ tmux attach-session -d -t my-session

By detaching all other sessions, you are ensuring that your machine's dimensions are the ones that tmux uses when drawing the window. This is a great quick fix if you're working on your own, but probably not what you want to do if you are in a pair programming situation.

source

Disassemble Some Codes

The RubyVM::InstructionSequence class makes it easy to compile, disassemble, and inspect bits of Ruby code. We can quickly take a peek under the hood at a simple ruby statement, such as a = 1 + 2, like so:

> ruby_code = 'a = 1 + 2'
=> a = 1 + 2
> compiled_code = RubyVM::InstructionSequence.compile(ruby_code)
=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
> puts compiled_code.disasm
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] a
0000 trace            1                                               (   1)
0002 putobject_OP_INT2FIX_O_1_C_
0003 putobject        2
0005 opt_plus         <callinfo!mid:+, argc:1, ARGS_SIMPLE>
0007 dup
0008 setlocal_OP__WC__0 2
0010 leave
=> nil

It is a bit archaic, but when we get to the line starting with 0002, we see values (1 and then 2) pushed onto the stack, then operated on, and finally set on the local variable a. Fun!

Switch Version of a Brew Formula

If you've installed a couple versions of a program via brew and you'd like to switch from the currently linked version to the other installed version, you can use the switch command. For instance, if you are on version 1.8.2 of phantomjs and you'd like to switch to 1.9.0, you can simply invoke:

$ brew switch phantomjs 1.9.0

More generically:

$ brew switch <formula> <version>

Stashing Only Unstaged Changes

If you have both staged and unstaged changes in your project, you can perform a stash on just the unstaged ones by using the -k flag. The staged changes will be left intact ready for a commit.

$ git status
On branch master
...
Changes to be committed:

    modified:   README.md

Changes not staged for commit:

    modified:   app/models/user.rb

$ git stash -k
Saved working directory and index state ...

$ git status
On branch master
...
Changes to be committed:

    modified:   README.md

h/t Chris Erin

Organizing tmux windows

If you use a number of tmux windows as part of your daily workflow, you may find that they get to be a bit of a mess from time to time. There are gaps in the numbering and they aren't laid out in the order you'd prefer. The movew command makes it easy to rearrange these windows.

If you have a window indexed at 2 and you want it to be the 4th window, then you can:

:movew -s 2 -t 4

If you have a gap such that the 4th and 5th windows are numbered 4 and 7, then you can focus the 7 window and simply invoke:

:movew

And that window will be reinserted at the next available slot, in this case, window 5.

List Filenames Without The Diffs

The git show command will list all changes for a given reference including the diffs. With diffs included, this can get rather verbose at times. If you just want to see the list of files involved (excluding the diffs), you can use the --name-only flag. For instance,

$ git show HEAD --name-only
commit c563bafb511bb984c4466763db7e8937e7c3a509
Author: jbranchaud <jbranchaud@gmail.com>
Date:   Sat May 16 20:56:07 2015 -0500

    This is my sweet commit message

app/models/user.rb
README.md
spec/factories/user.rb

Re-indenting Your Code

If you have pasted some poorly formatted code or you've written a portion of code in a way that mangled the indentation, you can quickly re-indent that code for you. Or at least do its best to try and indent it correctly.

Make a visual selection of the code that you want to re-indent and then hit =.

For instance, this ruby code

if this_thing
p something
else
p nothing
end

will be indented by Vim as

if this_thing
  p something
else
  p nothing
end

See :h = for more details on how vim decides what formatting and indenting it will do.

h/t Chris Erin

Vim Without The Extras

If you want to start up vim without loading all the usual plugins, you can supply the --noplugin flag

$ vim --noplugin coffee.rb

You can take things even further by instead telling vim to open without loading any plugins or configuration files. That is, you can tell vim to skip all initializations.

$ vim -u NONE coffee.rb

If you are used to lots of syntax highlighting, custom bindings, and other niceties, this may feel rather foreign.

h/t Jake Worth

All The Environment Variables

If you want to see all the environment variables defined on your machine, you can list them all out with printenv. If you are like me, you probably have a ton of them. Pipe it through less to make it easier to navigate and search through (i.e. printenv | less).

Viewing Man Pages with man.vim

In Quick Man Pages, I introduced K which shells out to the man page for the unix command under the cursor. It gets better though. Vim has a built-in plugin, man.vim, that you can enable which allows you to view man pages without shelling out.

Add the following to your .vimrc file

runtime! ftplugin/man.vim
" grep

Then save it and re-source the configuration with :source %.

With the man.vim plugin enabled, you can now move your cursor over the word grep and hit <leader>K which will pop open the man page for grep in a unnamed, split buffer.

Not only does this prevent context-switching when viewing a man page, but it also gives you the full power of vim over the content of the man page. You can search, you can yank text, or you can even pop open the man page for another command.

See :h ft-man-plugin for more details.

Push Non-master Branch To Heroku

When using git to deploy your app to Heroku, it is expected that you push to the master branch. When you run the following command

$ git push heroku master

Heroku will attempt to build and run your app. However, if you have a staging branch for your application that you want to push to your staging environment on Heroku, you cannot simply run

$ git push heroku staging

Heroku will only perform a build on pushes to the remote master branch. You can get around this, though, by specifying that your staging branch should be pushed to the remote master branch, like so

$ git push heroku staging:master

source

Cat A File With Line Numbers

You can quickly view a file using cat

$ cat Gemfile
source 'https://rubygems.org'


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.0'
# Use postgresql as the database for Active Record
gem 'pg'

With the -n flag you can view that file with line numbers

$ cat -n Gemfile
 1  source 'https://rubygems.org'
 2  
 3  
 4  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
 5  gem 'rails', '4.2.0'
 6  # Use postgresql as the database for Active Record
 7  gem 'pg'

tmux in your tmux

If you are running tmux locally and you shell into another machine to access tmux remotely, you will suddenly find yourself in tmux inception. You will have a tmux instance running within your local tmux instance. If you have the same prefix key set for both, then you may be wondering how you can send a tmux command to the inner tmux instance.

If you press your prefix twice (e.g. <C-a> <C-a>), then the second prefix will be sent to the inner tmux instance which will then be listening for the rest of your command. So, to open a new window within the inner tmux instance, you can hit <C-a> <C-a> c.

Pretend Generations

To get an idea of what a rails generate command is going to to generate, you can do a dry run with the -p flag or the --pretend flag. If you run

$ rails generate model post -p

then you will see the following output

    invoke  active_record
    create    db/migrate/20150513132556_create_posts.rb
    create    app/models/post.rb
    invoke    rspec
    create      spec/models/post_spec.rb
    invoke      factory_girl
    create        spec/factories/posts.rb

though those files will not have actually been created. You now know precisely what rails will generate for you.

source

Evaluating One-Off Commands

When I need to quickly test something out in Ruby, I will often reach for irb. However, there is an even quicker way to send a line of code to ruby for evaluation. Use the ruby binary with the -e flag followed by your line of ruby. For instance,

$ ruby -e 'puts Class.ancestors'
[Class, Module, Object, Kernel, BasicObject]

Conditional Class Selectors in Haml

You can assign a class selector to a tag in HAML like so:

%div.active

You can conditionally assign a class selector in a concise manner like so:

%div{ class: ( "active" if @thing.active? ) }

You can do multiple conditional class selectors with array syntax:

%div{ class: [ ("active" if @thing.active?), ("highlight" if @thing.important?) ] }

source

Word Count for a Column

Assuming I have a database with a posts table:

> select * from posts where id = 1;
 id |  title   |              content               
----+----------+------------------------------------
  1 | My Title | This is the content of my article. 

I can compute the word count of the content of a given post like so:

> select sum(array_length(regexp_split_to_array(content, '\s+'), 1)) from posts where id = 1;
 sum 
-----
   7 

source

Truthiness of Integer Arrays

We can consider the truthiness of [1] as follows:

> [1] == true
=> true
> Boolean(true)
=> true
> Boolean([1])
=> true

We can consider the truthiness of [0] as follows:

> [0] == false
=> true
> Boolean(false)
=> false
> Boolean([0])
=> true

The truthiness of [0] does not seem to be consistent.

See this JavaScript Equality Table for more details.

The Black Hole Register

Vim has a variety of registers for storing and moving around text. Vim also has a special register called the black hole register. This black hole register is associated with the _ character.

When writing to this register, nothing happens. This can be used to delete text without affecting the normal registers. When reading from this register, nothing is returned.

As stated in the docs, if you don't want to overwrite the unnamed register or some other register when deleting text, you can use the black hole register. For instance, deleting the current line without any register side-effects looks like this:

"_dd

See :h registers for more info on Vim's registers.

Create A File Descriptor With Process Substitution

Process substitution can be used to create a file descriptor from the evaluation of a shell command. The syntax for process substitution is <(LIST) where LIST is one or more bash commands.

$ cat <(echo 'hello, world')
hello, world

This is particularly useful for commands that expect files, such as diff:

$ diff <(echo 'hello, world') <(echo 'hello, mars')
1c1
< hello, world
---
> hello, mars

Sources: Brian Dunn and Bash Guide for Beginners

Vim Tips

Get some Vim tips with:

:h tips

Create A New File In A New Directory

From within a vim session, if you create a buffer for a new file in a directory that doesn't exist. For instance, let's say that /features doesn't exist and the new file is my_latest_feature_spec.rb:

:e spec/features/my_latest_feature_spec.rb

Vim's command line will inform you that this is a buffer for a [New DIRECTORY]. If you then make some changes and subsequently try to save the file, Vim will present you with:

"spec/features/my_latest_feature_spec.rb" E212: Can't open file for writing

This is because the containing directory doesn't exist. You can quickly create that directory with a combination of Vim filename shorthands and shelling out to the mkdir command.

:!mkdir -p %:h

The % is shorthand for the qualified path of the current file. The :h is a filename modifier that returns the head of the filename, that is, it resolves to the path with everything except the name of the file.

Thus, this command is essentially resolving to:

:!mkdir -p spec/features/

Vim will shell out with this command making directories for all non-existent directories in the given path. Now you can happily save your new file.

Count number of matches

You can use the search and replace functionality in vim to count the number of matches for that search like so:

:%s/transaction_id//n

You will see the result in the command tray like so:

8 matches on 8 lines

If you want to find matches global (that is, counting multiples per line), you can add the g flag:

:%s/transaction_id//gn

for a response like:

13 matches on 8 lines

Squeeze out the extra space

Remove all the excess spaces from a string using the squeeze method:

> "this  is   a string".squeeze(' ')
=> "this is a string"

Moving To A Specific Line

Often times when I open a new buffer, it is with the intention of moving to a particular line. For example, if I am trying to move to line 55 in the file, then I will hit 55j*. This works fine when I am dealing with a freshly opened buffer. That is, this works fine if I am starting from the top of the buffer.

In general, there is a better approach. I can move to an exact line number from normal mode with :{N} where {N} is the line number. So, if I want to get to line 55 regardless of where I am currently positioned in the buffer, I can simply hit :55<cr>.

* This actually is slightly inaccurate, it moves me to line 56, not 55. If I need to be precise, this doesn't cut it.

** Also, 55G apparently does the same thing.

Whole Line Auto-Completion

To get whole line auto-completion in Vim, you don't need a fancy plugin. It is built right in. There is a sub-mode of insert mode called X mode that allows you to do various kinds of special insertions. The ctrl-x ctrl-l binding corresponds to whole line completion. So, if you start typing a few characters and then (while still in insert mode) hit ctrl-x ctrl-l you will see a completed line that matches the initial characters you typed as well as a list of subsequent matches. You can cycle through the matches using ctrl-n and ctrl-p (going forward and backward, respectively).

The completion is done based on the configured completion sources. Generally, the completion sources will include the current buffer, other loaded and unloaded buffers, plus others. You can see which sources are configured with :set complete? and read more about the completion configuration at :h 'complete'.

Help For Non-Normal Mode Features

The majority of your time in vim will be spent in normal mode. You will often look to the documentation for help on any number of commands and bindings available in normal mode. For instance, to find out more about goto file, you may do :h gf. And if you want to read more about yanking lines of code, you may do :h y.

But what about commands and bindings that aren't found in normal mode? What if you want to read about yanking text from visual mode? What if you want to get more details on insert's x-mode? Doing :h y and :h ctrl-x, respectively, won't do the trick because vim thinks you are talking about normal mode bindings.

The docs for these and other non-normal mode features can be found by prepending i_ and v_ to the binding in question.

To get at the docs for yanking from visual mode:

:h v_y

And to read up on insert's x-mode:

:h i_ctrl-x

Marks Across Vim Sessions

Any mark set with a capital letter (that is, A-Z) is called a file mark. File marks can be used to move from file to file. File marks will also be written to the Vim Info file (~/.viminfo) which means that if you close Vim and open it again, it will still know about those file marks. This means that your file marks are persisted across vim sessions which will save you the trouble of having to redefine them each time.

A more detailed description of marks is at :help marks.

Previous Visual Select

Typing gv in normal mode will re-select the previous visual selection. This is great for when you are doing a search and replace on a visual selection and don't get the regex quite right on the first try.