Today I Learned

A Hashrocket project

Ready to join Hashrocket? Find Openings here and apply today.

152 posts by doriankarter @dorian_escplan

Print stacktrace in Elixir #ElixirLang

When you are trying to debug something it is usually helpful to see the stacktrace of what called a function.

If you’re inside of a try expression, and within the catch or rescue block, that’s easy - use the __STACKTRACE__ Special Form.

try do
    # NOPE
  ArgumentError ->
    IO.puts("Stacktrace #{inspect(__STACKTRACE__)}")
  value ->
  # NOPE
  # NOPE

For all other cases the incantation is a little more complicated (and if you don’t think you can remember it, perhaps set up a snippet):

|> IO.inspect(label: "---------> stacktrace")

What's my public IP? #automation #linux #terminal

Ever wonder what your public IP looks like? When I do, I usually search for “what’s my ip” and it is nice enough to tell me that at the top above the search results.

But what if I want to do that at the terminal, and perhaps use that information in a script?

TIL about! curl it and you get your ip, hostname, city, state, zipcode, country, ISP, timezone, even lat & lng coordinates of the rough location!

  "ip": "",
  "hostname": "",
  "city": "Chicago",
  "region": "Illinois",
  "country": "US",
  "loc": "41.8500,-87.6500",
  "org": "AS7922 Comcast Cable Communications, LLC",
  "postal": "60666",
  "timezone": "America/Chicago",
  "readme": ""

This information is not fully accurate, but it’s good enough for scripts, and because it comes back in json form you can pipe it to jq to extract info or read it directly into your scripts.

No ifconfig on Linux?

If you are on a Linux machine and trying to run ifconfig you may get Command not found: ifconfig. That is because some Linux distros don’t come with it bundled by default.

On Manjaro Linux which is an Arch Linux based distro you can use pacman to install the package containing ifconfig called net-tools:

sudo pacman -S net-tools

On Debian based distros you can use:

sudo apt-get install net-tools

If you don’t want to install net-tools you can try using the ip command:

ip addr

This will return the interfaces on your machine and their IP bindings.

What does that git alias do? 🕵️‍♂️

I have some git aliases in my dotfiles and sometimes I use an alias for too long that I actually forget what it does under the hood.

I can open my ~/.gitconfig file in nvim (which I have an alias for) and search for the line that introduced the alias, but when pairing sometimes it’s easier and faster to just use git help to get the definition of an alias:

git help doff
'doff' is aliased to 'reset HEAD^'

Use pgrep and xargs to kill (processes) #zsh #bash

Have you ever found yourself doing this:

ps aux | grep [b]eam

And then copying the pids one by one so you can pass them to kill?

There’s a better way to return just the pids of the process you care about and not having to worry about ps finding your grep call (that’s why I’m surrounding the b in beam with square brackets).

pgrep -f beam

This will return just the pids, one in each line (which is perfect for use with xargs)

Example output:


Use with xargs to kill (-9 for extra brutality points 😈):

pgrep -f beam | kill -9

Debugging: Elm evaluates uncalled `let` variables

If you write a function that has a let expression variables like so:

view : Model -> Html Msg
view model =
        logModel = Debug.log "model:" model
      div []
          [ button [ onClick Increment ] [ text "+1" ]
          , div [] [ text <| String.fromInt model.count ]
          , button [ onClick Decrement ] [ text "-1" ]

When the view function is called you will see the console log message that logModel writes, even though it was never called from the function’s body.

This can be useful for debugging function arguments coming in, or other variables without messing with the function’s body.

To avoid the [elm-analyse 97] [W] Unused variable "logModel" warning you can use an underscore instead of naming the variable:

example =
        _ = Debug.log "foo" "bar"
      "function body"

It is worth mentioning that variables that are called from a function’s body will only be executed once.

example =
    foo = Debug.log "foo" "I'm called once"
    bar = Debug.log "bar" "I'm called once"

will result in only two console log messages, one for foo, and one for bar.

h/t Jeremy Fairbank

Pretty-Print JSON in NeoVim/Vim using jq

I’ve written here before about how to pretty-print JSON in Vim but since then I have found an even easier method using jq.

jq is an amazing command line utility for processing, querying and formatting JSON. I use it all the time when I get a response from an API request and I want to extract information or simply to pretty-print it with colors. All you have to do is pipe the curl results into jq:

curl | jq


You can also use jq inside of NeoVim to pretty print a JSON string, right in your buffer using this command:



Get a writable temporary directory in Elixir

When you need to write a temporary file to disk it is common to assume a particular path exists based on the operating system the app is running on:

tmp_file = Path.join("/tmp", filename)

However depending on the configuration of the app as it is deployed in production, it may not have access to the /tmp directory. Fortunately Elixir provides a function that returns a writable path for temporary files:

dir = System.tmp_dir!()
tmp_file = Path.join(dir, filename)

From the docs (h System.tmp_dir):

Writable temporary directory.

Returns a writable temporary directory. Searches for directories in the following order:

    1. the directory named by the TMPDIR environment variable
    2. the directory named by the TEMP environment variable
    3. the directory named by the TMP environment variable
    4. C:\TMP on Windows or /tmp on Unix
    5. as a last resort, the current working directory

Returns nil if none of the above are writable.

I prefer to use the “bang” version System.tmp_dir! described as:

Same as tmp_dir/0 but raises RuntimeError instead of returning nil if no temp dir is set.

On my machine it returns something like this:


🔒 Serve Phoenix App Locally with HTTPS 🔒

The Phoenix Framework provides an easy mix task to automatically generate a self-signed SSL cert. This is useful if you want to test the app locally with HTTPS.

mix phx.gen.cert

The self-sigend certs will be stored in priv/cert so make sure you add that path to your .gitignore.

When finished the command will prompt you to update your endpoint configuration and a few imporant warnings:

If you have not already done so, please update your HTTPS Endpoint
configuration in config/dev.exs:

  config :tilex, TilexWeb.Endpoint,
    http: [port: 4000],
    https: [
      port: 4001,
      cipher_suite: :strong,
      certfile: "priv/cert/selfsigned.pem",
      keyfile: "priv/cert/selfsigned_key.pem"

WARNING: only use the generated certificate for testing in a closed network
environment, such as running a development server on `localhost`.
For production, staging, or testing servers on the public internet, obtain a
proper certificate, for example from [Let's Encrypt](

NOTE: when using Google Chrome, open chrome://flags/#allow-insecure-localhost
to enable the use of self-signed certificates on `localhost`.

Optimize Images for the Web the Easy Way

TIL I learned about a really useful, open source, image optimization app called ImageOptim. This app will help you batch resize image files (png, jpg, gif) in either lossless or lossy way.


It is so much quicker than using an image editor such as Affinity Photo. And best of all it’s free!

It has helped me cut image sizes by as much as 94%! All without noticeable compression artifacts.

To install it on macOS simply run:

brew cask install imageoptim

For source and more info:



Clean stopped containers & dangling images #docker


docker container prune


No one likes dangling images…


dangling_images=$(docker images -qf dangling=true)


Then delete the images

docker rmi $dangling_images



Delete lines from file with sed

Imagine the following file:



If you want to delete a line matching a regular expression (e.g. hellosed), you can use d at the end of your regular expression.

sed '/hellosed/d' sed.test



However the file did not change:

cat sed.test


To write the file in place use the -i [suffix] option. This argument allows you to specify the suffix of the backup file to be saved before committing your changes. For example:

sed -i '.bak' '/hellosed/d' sed.test

Now the file will be modified with our changes but we will also get a backup of the original file in sed.test.bak.

If you like living on the edge 🛩, and don’t want those pesky backup files littering your system, you can supply -i with an empty suffix, causing no backup file to be saved.

sed -i '' '/hellosed/d' sed.test

The paste event in browsers

Browsers allow you to capture a paste event in a DOM element [1][2].

This event fires before any clipboard data is inserted into the document, which makes it ideal for manipulating the data and pasting the manipulated data instead.

In Today I Learned by Hashrocket we recently utilized this feature to enable pasting images straight into the post editor. The image is then uploaded to and the resulting URL is pasted as a Markdown Image Tag into the textbox.


If you are interested in adding similar functionality to your site check out this PR.

Also consider hosting your own fork of TIL.

Install node modules in subdir without a CD

So yea you don’t need a friend to send you a CD-ROM anymore to install node modules. You can use the World Wide Web! Pretty exciting.

On a more serious note, if your front-end is stored in a sub directory of your project, for example:

❯ tree -d -L 2
├── assets
|   ├── package.json
|   └── package-lock.json
└── app

Normally you would cd into assets, run npm i, and cd back out to the project root so you can go back to doing important things:

cd assets
npm i
cd -

Or you can push and pop, cause you’re kinda smart

pushd assets && npm i && popd

Or if you’re a really cool kid you’d use a sub-shell

(cd assets && npm i)

But wait! There’s another option - use the prefix CLI option in NPM!

npm i --prefix assets

It works really well for those long Dockerfile RUN statements.

Delete remote git branch - the declarative way

Cleaning up after yourself is important, and not just in real life. Good Git Hygiene™ goes a long way.

One of the methods I like to clean up is deleting unused feature branches. I do that both locally and on the remote source control server (github/gitlab etc).

As is common with Git there are many ways to feed a cat. Some people use this:

git push origin :name-of-branch

I prefer the more declerative way, especially for potentially destructive operations such as deleting a remote branch:

git push origin --delete name-of-branch

Either way, keeping your remote branches trim makes for a happier development team!

Pipe all output from a command (stderr & stdout)

When you write a bash/zsh script relying on pipes normally you will not be able to pipe through text from the stderr output with a normal pipe.

For example, curl -v prints some information about the request, including it’s headers and status into stderr.

If we simply try to pipe the output of curl -v into less we will not see the verbose header and request info:

curl -v | less


<html lang='en-US'>
<meta charset='UTF-8'>
<title>Ruby on Rails, Elixir, React, mobile design and development | Hashrocket</title>

But if we want the stderr output as well we can use the |& syntax:

curl -v |& less


* Rebuilt URL to:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
* Connected to ( port 443 (#0)
<html lang='en-US'>
<meta charset='UTF-8'>

🍒 Bonus:

We can also pipe through ONLY the stderr:

curl -v |1>& less

Output (will not contain the html response):

* Rebuilt URL to:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

h/t Thomas Allen

Get ONLY PIDs for processes listening on a port

The lsof utility on Linux is useful among other things for checking which process is listening on a specific port.

If you need to kill all processes listening on a particular port, normally you would reach for something like awk '{ print $2 }', but that would fail to remove the PID column header, so you would also need to pipe through tail -1. It get pretty verbose for something that should be pretty simple.

Fortunatly, lsof provides a way to list all the pids without the PID header specifically so you can pipe the output to the kill command.

The -t flag removes everything from the output except the pids of the resulting processes from your query.

In this example I used a query to return all processes listening on port 3000 and return their PID:

lsof -ti tcp:3000

The output of which will look something like:


This is perfect for piping into kill using xargs:

lsof -ti tcp:3000 | xargs kill

No awks or tails necessary! 🐕

Copy files with progress in terminal w/rsync

When you need to transfer a lot of files from one location to another it’s sometimes useful to have some progress indication and maybe even a speed measure, or time remaining.

I recently had to transfer a few gigabytes of data from one computer to another. For this task I chose to use Rsync, since it is a command line utility that can preserve file metadata (permissions) and easily resume in case of an error.

Rsync ships with macOS by default, but if you want to get a more recent version, you can install it from homebrew.

There are two options for showing progress:

If you are transferring a few really big files you can use the --progress flag.

rsync -ah --progress source destination

This will list each file as it being transferred and show you the progress and speed in which the file is being transferred.

In my case I had a lot of small files so I chose to use --info=progress2.

rsync -ah --info=progress2 source destination

This will output something like this

2.26G  16%    6.13MB/s    0:05:51 (xfr#375313, to-chk=0/1165396)

Which represents the progress, speed and estimated time remaining for the entire transfer.

Show escaped bash color codes in less #linux

My ls command colors directories and files according to their type and permissions:

ls with color

But when the window is too small to fit the content I pipe the result into less:

less broken

Which cannot correctly parse the escape code from ls and turn them into color. To fix that add -r to the less command:



My l alias is gls -F -G --color --group-directories-first -lah (gls is GNU ls)

You can alias less=less -r if you want this to be the default behavior for less.

Vim: Peek horizontally without moving the cursor

Some people like wordwrapping in Vim. Personally I find it annoying for code because it can destroy the meaning of the code in the context that it was formatted in by the original author, making it hard to understand where one line begins and ends.

Turning wordwrap off though, can put you in a situation where you have a line of text slightly longer than the screen can show, and you may want to scroll a bit to the right/left for reference but not move your cursor and lose your position with ^ or $.

Vim allows you to do that with zs and ze mappings.

DEMO demo

Learn more with :h zs or :h ze.

Show materialized view definition in #postgresql

PSQL offers a handy \dv function for showing the definition of a view. That function does not seem to work on materialized views.

To see the definition of a materialized view use the following instead:

select pg_get_viewdef('search_documents');

Another option is to use \d+ search_documents which shows both the query and the columns.

(Replace search_documents with the name of your view.)

Hide all other windows on #macOS

Sometimes your desktop gets cluttered with windows of different running applications which makes it difficult to concetrate on the task at hand.

This can also come in handing when sharing your screen or presenting.

Fortunately macOS offers some shortcuts to remediate this common problem:

⌘+h - hide current window

⌘+⌥+h - hide all other windows

⌃+⌘+f - toggle full screen mode

Using `yarn global` w/ Node through asdf (mac)

The asdf version manager is an awesome tool for managing many different language runtime versions. I recently started using it for Node and noticed that yarn global no longer plays nice with it.

Turns out that if you install yarn through homebrew - your global directory will not take into account the asdf node version and path.

To correct this, first uninstall yarn from homebrew:

brew uninstall yarn

Then in your .zshrc or equivalent remove the yarn global path (see my previous post about Yarn global)

Now you want to find where asdf is being sourced into your .zshrc and insert a dynamic yarn global path:


# asdf global version manager
source "$HOME/.asdf/"
source "$HOME/.asdf/completions/asdf.bash"

# set yarn binaries on path
# must be below the .asdf source commands ^
export PATH="$(yarn global bin):$PATH"

You can now install yarn again from npm which will put it in your asdf versioned node:

npm i -g yarn

When done restart your terminal and test to see that everything worked. I had to delete the ~/.config/yarn/global to make this work.

echo $PATH should contain something that looks like /Users/dkarter/.asdf/installs/nodejs/9.11.1/.npm/bin which should match yarn global bin.

Custom errors in JavaScript ⚠️

Javascript provides the ability to create custom errors by modifying the prototype of a function to the Error protorype. This is how one would create a custom error:

function ValidationError(message) { = 'ValidationError'; 
  this.message = message; 
ValidationError.prototype = Error.prototype;

throw new ValidationError('the form is invalid');

To catch it you can check the class of an error using instanceof:

try {
    // do stuff
  throw new ValidationError('the form is invalid');
} catch (ex) {
    if (ex instanceof ValidationError) {
    alert(ex.message); // the form is invalid
  } else {
    // crash and burn
    throw ex;

📅 Get beginning and end of week with Moment.js

To get the date for beginning of week for a date in moment you can use the startOf and endOf functions on moment objects.

const today = moment();
const from_date = today.startOf('week');
const to_date = today.endOf('week');
  from_date: from_date.toString(),
  today: moment().toString(),
  to_date: to_date.toString(),

// {
// }

NOTE: Remember that the start of week will depend on the user’s locale settings on their machine. If you want to use start of week based on ISO 8601 you can use moment().startOf('isoWeek');

The same technique can be used for start of month (startOf('month')), start of year (startOf('year')) and even quarter (startOf('quarter');).

Case insensitive `in` query in #postgres #psql

If you have a list of strings and you want to query a column to get all the matching records, but you do not care about the casing, Postgres offers a cool and easy way of doing that with the citext extension.

Given this table:

id | company_name
 1 | Abibas
 2 | Nykey
 3 | Pumar

We want to match the following:

select company_name
from vendors 
where company_name in ('Abibas', 'NyKey', 'PUMAr');

First you will have to make sure you have the citext extension created if you haven’t already:

create extension citext;

Then you can cast the searched field to citext:

select company_name
from vendors 
where company_name::citext in ('Abibas', 'NyKey', 'PUMAr');

h/t joshbranchaud for helping me find this

Delete all node_modules dirs recursively with find

If you have hundreds of past JavaScript projects sitting in your workspace folder, you probably also have hundreds of node_modules folders nested inside of them, and hundreds of thousands actual npm modules resting peacefully in those.

Often enough all you care about is the code that uses the modules and not the modules themselves, so to save yourself some precious laptop diskspace you can just delete all those folders! When you need them again cd into the project directory and run yarn install or npm install.

First let’s do a dry run:

find . -name "node_modules" -type d -prune

and now that you checked the output of the above command you can delete all the nested node_module folders.

If you are still feeling paranoid (and you’re on macOS) you can simply move those to the Trash:

find . -name "node_modules" -type d -prune -exec trash '{}' +

If you feel a little braver just unlatch the airlock and toss them into a black hole 🕳 using rm -rf

find . -name "node_modules" -type d -prune -exec rm -rf '{}' +

I saved a whopping 80GB with this technique 🤑. Hope you find it helpful.

Use a proxy on curl/wget commands

Using a proxy can be a good way to debug http issues. Unfourtunately setting the proxy on macOS globally does not apply to all command line utilities.

On Curl for example you can set the proxy using the --proxy flag:

curl --proxy

Or by adding the following to your ~/.curlrc configuration file for a more persistent setting:

proxy =

A similar thing can be done with the wget utility by editing the ~/.wgetrc and adding:

http_proxy =

Get application's current version in production


To verify the version:

  1. SSH into your server
  2. navigate into the bin directory of your release (e.g. app_release/your_project/bin)
  3. run the remote console ./your_project remote_console
  4. Run the spec function on Application: Application.spec(:your_project, :vsn)

You will get back a string such as ‘0.0.1’.

Difference between output of two commands #linux

Recently I’ve been playing around with ripgrep (rg) which is a tool similar to Ack and Ag, but faster than both (and written in Rust FWIW).

I noticed that when I ran a command in Ag to list all file names in a directory, and counted the number of files shown, I was getting a different number than the comparable command in ripgrep.

ag -l -g "" | wc -l
# =>      29
rg -l "" | wc -l
# =>      33

This led me to wonder if there is an easy way to view the diff between the output of the two commands.

I know I can save the output into a file and then compare the two files with the builtin diff command in linux, however I don’t see a reason to write to disk for such a comparison.

This is how you would do that without writing to disk:

diff <(ag -l -g "") <(rg -l "")

The diff printed out by this command is inaccurate, so you will need to add a sort to each command:

diff <(ag -l -g "" | sort) <(rg -l "" | sort)

Pipe text into Vim from stdin

You can pipe text into vim directly from stdin. This can be helpful if you want to edit the output of a long bash command, or if you want to see what an installation script contains before piping it into bash.

curl -fsSL | vim -

The key is to use the - after the vim command to make it read from stdin. This will open a new buffer with the output of the previous command.

Postgres automatically appends timezone

Dates can be notoriously hard, particularly when it comes to timezones.

If you select a date without timezone information and cast it to a data type w/timezone, Postgres will assume the timezone of the server:

select '2000-01-01'::timestamptz;
│      timestamptz       │
│ 2000-01-01 00:00:00-06 │

I’m located in CST hence the -06 at the end of the time specification (6 hours before UTC time).

To use a specific timezone such as UTC, instead of your server’s timezone which can be pretty arbitrary:

select '2000-01-01'::timestamptz at time zone 'UTC';
│      timezone       │
│ 2000-01-01 06:00:00 │

Postgres now displays the time in UTC. Still probably not what you expected (6am?) - Postgres infers the 00:00:00 time in your timezone and converts it to UTC (in my case adding 6 hours).

So how would you get it to show 00:00:00 and still be in UTC timezone?

select '2000-01-01 00:00:00 UTC'::timestamptz at time zone 'UTC';
│      timezone       │
│ 2000-01-01 00:00:00 │

If you use timezone aware data types it is recommended to always specify the timezone when inserting data, otherwise you are in for a world of trouble.

Quick syntax reference for #SQL directly in #psql

Whenever I forget the syntax for a certain SQL command in Posgres I usually reach for Dash or simply search DuckDuckGo for the the specific command. That usually yields the Postgres official documentation website which is great…

Wouldn’t it be nice though if I could stay right inside psql and get the documentation I am looking for?

It would.. and it’s possible:

\h create index

create index screenshot

Use \h followed by the SQL command - this is not the full verbose documentation that you would find on the Postgres docs website but it’s more of a syntax reference - which is most of the time what you need.

If you are not sure what to type or simply want to explore new commands try typing \h without anything after it - you will see something like this:

slash h by itself screenshot

Treat words with dash as a word in Vim

By default vim treats two words connected with an underscore e.g. search_tag as a vim word text-object.

This is very useful because you can then use motions and commands on them such as daw to delete a word, or ciw to change inside the word.

That is not the case for dash separated words e.g. search-tag. These types of words are very common in CSS class names and HTML IDs.

To make vim treat dash separated words as a word text-object simply add the following to your .vimrc:

set iskeyword+=-

And source it again.

Jump between #git hunks in Vim with vim-gitgutter

One of my favorite Vim plugins is vim-gitgutter - it shows gutter markings for changes in the current buffer when that file is tracked by git.

It looks like this:

+ = new lines - = deleted line ~ = changed line

It also comes with a few very useful commands for working with hunks, sections of changed code in your file.

To jump between hunks you can use ]c and [c. Since I don’t really use the return and backspace keys in normal mode I have mapped those instead:

nnoremap <silent> <cr> :GitGutterNextHunk<cr>
nnoremap <silent> <backspace> :GitGutterPrevHunk<cr>

This is especially useful on big files (more than a bufferful) with scattered changes.

Simple text file #encryption with Vim


set cryptmethod=blowfish2

This will set the encryption to the strongest algorithm vim supports.


$ vim -x mysecret.txt




NOTE: this will not work with NeoVim.

List all available extensions in #Postgres

Postgres comes packed with extensions just waiting to be enabled!

To see a list of those extensions:

select * from pg_available_extensions;

This will list the extension’s name, default_version, installed_version, and the comment which is a one liner description of what the extension does.

Here’s an interesting one for example:

name              | earthdistance
default_version   | 1.1
installed_version | ø
comment           | calculate great-circle distances on the surface of the Earth

To enable an extension, simply call create extension on the name:

create extension if not exists earthdistance;

whatis command and apropos in #linux #bash

Ever wonder what a command you are using is? Turns out linux has the answers for you!

Simply type whatis followed by the name of the command.


$ whatis bc
bc(1)         - An arbitrary precision calculator language
$ whatis brew
brew(1)       - The missing package manager for macOS
brew-cask(1)  - a friendly binary installer for macOS

whatis uses the man pages to search your entered query.

There is also a reverse search, which searches the descriptions of commands. For example say you are looking for a calculator:

$ apropos calculator
bc(1)         - An arbitrary precision calculator language
dc(1)         - an arbitrary precision calculator

h/t this tweet by Peter Cooper

Stop #bash script on error #linux #zsh

If you are writing a procedural bash script, you may want to stop execution if one of the steps errored out.

You can write error handling for each step, but that can get quite verbose and make your script hard to read, or you might even miss something.

Fortunately bash provides another option:

set -e

Simply place the above code at the top of your script and bash should halt the script in case any of them returns a non-true exit code.

Caveats: this will not work in all cases, for example it does not work for short circuited commands using &&/||.

If you want it to work when one of your operations in a pipe fails you will need to add the pipefail flag (not supported on some systems set -o | grep pipefail to check your system):

set -e -o pipefail

If you have a script that always returns a non true return code and that’s fine you can override set -e for that command with:

set +e
set -e

At this point I consider it a best practice to include this statement in every script I write.

List filenames of multiple filetypes in project

Ag (aka The Silver Searcher) is an amazing piece of software. It allows you to define file types (like Ack) and comes prepackeged with some file types.

Using this feature you can list all files of a specific type in your project. For example say we want to list all Ruby and JavaScript files:

ag --ruby --js -l

Ag has the added benefit over Ack, that it ignores gitignored files, so you only get the files that matter (and not stuff from node_modules etc).

To see what filetypes Ag supports:

ag --list-file-types

The list is pretty extensive! Unlike Ack however, there is currently no way to add new file types or extend the list.

Make console.log stand out with custom css style

I know your browser console is full of messages because you are debugging something, and that creates a lot of noise. Now you are adding a new console.log, and you need it to stand out above the rest.

Maybe you are like facebook and just want to warn your users from pasting in code in the browser in social engineering attacks.


To style a console.log message use the %c interpolation and pass it a css style. e.g.

console.log('%c%s', 'color:red;font-size:5em', alert)

In the example above %s means inerpolate the object into the output string.


Compatibility: tested to work on Firefox, Chrome, and Safari.

h/t Dillon Hafer

Storing recurring schedules in #Rails + #Postgres

If you have a scheduling component to your Rails application you may need to store the day of week and time of day in the database.

One way to store the day of week is to use an integer column with a check constraint that will check that the value is between 0 and 6.

create table schedules (
  id serial primary key,
  day_of_week integer not null check(day_of_week in (0,1,2,3,4,5,6)),
  beg_time time not null,
  end_time time not null

Then when you read it back from the database and need to convert it back to day name you can use Date::DAYNAMES. e.g.:

[2] pry(main)> require 'date'
=> true
[3] pry(main)> Date::DAYNAMES
[4] pry(main)> Date::DAYNAMES[0]
=> "Sunday"
[5] pry(main)>

If you need to store time of day as entered (in a time without timezone column - as specified above) check out the wonderful Tod gem by Jack Christensen