Today I Learned

A Hashrocket project

Pivoting a 2-dimensional list

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

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

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

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

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

Disable a pathogen plugin

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

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

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

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

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

PostgreSQL "RETURNING"

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

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

Check this out:

DROP TABLE IF EXISTS users;

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

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

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

h/t @joshuadavey

Map Caps Lock to Escape in macOS Sierra #seil

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

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

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

  1. Download and install Karabiner-Elements:

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

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

    disable capslock

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

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

    And add the following to it:

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

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

Vim undo tree

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

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

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

So here's an example to follow:

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

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

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

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

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

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

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

You can check gundo vim plugin for tree visualization.

ExtractRspecLet

From the Hashrocket Vault...

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

# spec/model/foobar_spec.rb

foo = FactoryGirl.create :foobar

To this:

# spec/model/foobar_spec.rb

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

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

h/t Josh Davey and Dillon Hafer

Aggregate Expressions with FILTER in Postgresql

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

See this example:

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

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

h/t @joshuadavey

Vim Regex Word Boundaries

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

Given this file:

foo
foobar

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

:%s/foo/baz/g

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

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

Merge maps with a callback

Merging two maps together is something I'm familiar with:

iex> Map.merge(%{a: 1, b: 2}, %{c: 3})
%{a: 1, b: 2, c: 3} 

But this function suffers from a unilateral decision that's made when a key in the first argument also exists in the second argument. The value from the first map always overwrites the value from the second.

iex> Map.merge(%{a: 1, b: 2, c: 100}, %{c: 3})
%{a: 1, b: 2, c: 100}

But Elixir's Map module has a merge function that takes a function as an additional argument. It lets you decide what to do in case of a key conflict. You could write this function so that the second argument overwrites the first or better yet add the two values together.

iex> Map.merge(%{a: 1, b: 2, c: 100}, %{c: 3}, fn(k, v1, v2) -> v1 + v2 end)
%{a: 1, b: 2, c: 103}

Three data types that go `into` a Map

Enum.into can be used to put different types of things into different types of collections. For instance I can put elements from one list into another list.

iex> Enum.into([4], [1,2,3])
[1, 2, 3, 4]

It works with Maps too and there's different types of things than can go into a map. A map can certainly go into another map:

iex> Enum.into(%{"a" => 1}, %{"b" => 2})
%{"a" => 1, "b" => 2}

Keyword lists also go into a map:

iex> Enum.into([a: 1], %{"b" => 2})
%{:a => 1, "b" => 2}

And lists of tuples also go into a map:

iex> Enum.into([{"a", 1}], %{"b" => 2})
%{"a" => 1, "b" => 2}

But only when there are two elements in the tuple:

iex(32)> Enum.into([{"a", 1, 3}], %{"b" => 2})
** (ArgumentError) argument error
    (stdlib) :maps.from_list([{"a", 1, 3}])
    (elixir) lib/enum.ex:1072: Enum.into/2

Migrate from MySQL to Postgres

Today I wanted to see if a large client app would see any performance improvement using Postgres vs. MySQL.

Luckily there is a great tool called pgloader that can quickly scan and import a MySQL DB right into Postgres.

Homebrew FTW!

$ brew install pgloader

Create an import script to define the connection strings to each of your databases and configuration the import options you want.

-- import_mysql.load
LOAD DATABASE
FROM mysql://root@localhost/db_name
INTO postgresql://localhost/db_name

 WITH include drop, create tables, no truncate,
      create indexes, reset sequences, foreign keys;

Run the import:

$ pgloader import_mysql.load

If you get this error:

An unhandled error condition has been signalled:
   MySQL Error [1055]: "Expression #6 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'information_schema.rc.UPDATE_RULE' which is not functionally dependent on columns in GROUP
 BY clause; this is incompatible with sql_mode=only_full_group_by"

Then create a MySQL configuration file (if you don't have one already) and open it:

$ sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
$ sudo vim /etc/my.cnf

Make sure ONLY_FULL_GROUP_BY is not in the mode list:

# /etc/my.cnf
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Now restart MySQL and try to import with pgloader again.

Rails Runner Shebang Line

I've known about the Rails Runner command for a long time - all it does is execute some Ruby in the context of your app. I've rarely used it, but had a situation today where I wanted to. I couldn't quite remember how it worked, so I ran it without any arguments and discovered something new (to me, anyway):

$ rails runner
...blah, blah, blah...
You can also use runner as a shebang line for your executables:
-------------------------------------------------------------
#!/usr/bin/env /Users/jon/project/bin/rails runner

Product.all.each { |p| p.price *= 2 ; p.save! }
-------------------------------------------------------------

Whoa, Rails gives you the runner as a shebang line too!!

Using Ruby Hash in `gsub`

Ruby String#gsub method also accepts a hash as second argument. This is perfect for some situations like mapping a phone-word to phone number:

phonewords = {
  'a' => 2, 'b' => 2, 'c' => 2,
  'd' => 3, 'e' => 3, 'f' => 3,
  'g' => 4, 'h' => 4, 'i' => 4,
  'j' => 5, 'k' => 5, 'l' => 5,
  'm' => 6, 'n' => 6, 'o' => 6,
  'p' => 7, 'q' => 7, 'r' => 7, 's' => 7,
  't' => 8, 'u' => 8, 'v' => 8,
  'w' => 9, 'x' => 9, 'y' => 9, 'z' => 9,
}
phone = "1-800-map-gsub"
puts phone.gsub(/[a-z]/, phonewords)
# => 1-800-627-4782

h/t @joshuadavey

Use PostgreSQL socket in database.yml 🐘🔌

When using the host: configuration option in the database.yml set to localhost or 127.0.0.1, I would need to add an entry to PostgreSQL's pg_hba.conf file to allow my ip address access. But, if you give the host: option the directory of your PostgreSQL sockets, rails will be able to use the socket, without needing to add an entry to the PostgreSQL configuration file.

production:
  database: fancy_things
  host: '/var/run/postgres'
  ...

Using assigned value later in same pattern match

I have an array of character lists.

['apple', 'aardvark']

And I want to make sure that each of these two items has the same beginning letter.

I can do this with pattern matching because variables can be reused in an assignment.

iex > [[c | _], [c | _]] = ['apple', 'aardvark']
['apple', 'aardvark']
iex > c
97

Here's what happens when the first letter does NOT match.

iex > [[c | _], [c | _]] = ['apple', 'hamster']
** (MatchError) no match of right hand side value: ['apple', 'hamster']

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"

Remove both scrollbars from MacVim

If you use MacVim you may encounter the gray Mac OS scrollbar on the right side.

When you split the window you may encounter two scrollbars, one on each side.

I find that to ruin the look of MacVim, especially with a dark colorscheme (I use Dracula).

example

To remove only the left one use

set guioptions=r

This will tell vim to always show the right scrollbar only. To remove only the right one use

set guioptions=l

To remove all scrollbars, remove everything after the equal sign viml set guioptions=

example

Add this to your vimrc for a consistent experience.

Spellcheck Attribute

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

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

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

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

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

Run ExUnit tests in the order they are defined

You might have a test module like this.

ExUnit.start

defmodule TestOrderTest do
  use ExUnit.Case

  test "first" do
    assert true
  end

  test "second" do
    assert true
  end
end

And when you run it, second runs before first!

In general this is fine, because every test should pass no matter which one runs first. In certain circumstances however, lets say you're working through some Exercism.io challenges, you might want them to run in order.

To do so include the configuration seed: 0

Elixir.configure seed: 0

And tackle every test in the order they've been given to you!

Rails Enum with prefix/suffix

Today I learned that Rails 5 released new options for enum definition: _prefix and _suffix.

class Conversation < ActiveRecord::Base
  enum status:          [:active, :archived], _suffix: true
  enum comments_status: [:active, :inactive], _prefix: :comments
end

conversation.active_status!
conversation.archived_status? # => false

conversation.comments_inactive!
conversation.comments_active? # => false

h/t @joshuadavey

Rails Enums and PostgreSQL Enums

Today I learned that Rails Enum works pretty well with PostgreSQL Enum.

Enum in PostgreSQL work as a new type with restricted values and if you need to guarantee data integrity there's no best way to do that than in your database. Here is how we create a new enum in PostgreSQL and use in a new column:

class AddEnumToTrafficLights < ActiveRecord::Migration
  def up
    ActiveRecord::Base.connection.execute <<~SQL
      CREATE TYPE color AS ENUM ('red', 'green', 'blue');
    SQL

    add_column :traffic_lights, :color, :color, index: true
  end

  def down
    remove_column :traffic_lights, :color

    ActiveRecord::Base.connection.execute <<~SQL
      DROP TYPE color;
    SQL
  end
end

In Rails models I prefer to use Hash syntax when mapping Ruby symbols to database values.

class TrafficLight < ApplicationRecord
  enum color: {
    red: 'red',
    green: 'green',
    blue: 'blue',
  }
end

And now Enum in action:

TrafficLight.colors
#=> {
#=>   "red"=>"red",
#=>   "green"=>"green",
#=>   "blue"=>"blue"
#=> }
TrafficLight.last.blue!
TrafficLight.last.color
#=> "blue"

h/t @ joshuadavey

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"

Expecting change with RSpec #rails #testing #rspec

Usually when I try to test if a value has changed after a method has been called I will assert the initial value as one expectation followed by the action that changes it, and finally assert the value has changed.

For example this test will check if a user's bad login attempts are incremented when the user.record_bad_login! method is called:

describe '#record_bad_login!' do
  let(:user) { FactoryGirl.create(:user) }

  it 'increments the bad login attempts count' do
    expect(user.failed_login_attempts).to eq(0)
    user.record_bad_login!
    expect(user.failed_login_attempts).to eq(1)
  end
end

RSpec provides us with a more straight forward way to oneline this type of test while making it more declarative:

describe '#record_bad_login!' do
  let(:user) { FactoryGirl.create(:user) }

  it 'increments the bad login attempts count' do
    expect { user.record_bad_login! }.to change { user.failed_login_attempts }.from(0).to(1)
  end
end

Read more here: https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-change

Shell ! command

!! is well known to repeat the last shell command in a *nix terminal, it turns out there are other useful variants:

Given a shell history:

$ history
10034  echo $PATH
10035  history
10036  type ruby
10037  which ruby
10038  history
10039  ls

!n - execute a specific item:

$ !10039
ls
Applications
Desktop
...

!?<match>?: matches a pattern and runs the first command that matches:

$ !?uby?
type ruby
ruby is /Users/jason/.rvm/rubies/ruby-2.2.2/bin/ruby

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

Toggle CursorLine, CursorColumn w/Vim Unimpaired

Vim Unimpaired plugin by Tim Pope ships with a shortcut for quickly toggling CursorLine and CursorColumn. This is particularly useful on large files with plenty of syntax highlighting.

Turning CursorLine/CursorColumn off can speed buffer navigation by reducing the blocks being re-rendered on the screen, making Vim snappy again.

To use this shortcut type cox from NORMAL mode and Vim will toggle CursorLine and CursorColumn on and off.

h/t Chris Erin

DEMO: demo

Two swings at guassian distribution in Postgres

I've come across 2 ways to replicate a bell curve.

This is adding 3 random numbers together.

select 
floor(random()*3)+floor(random()*3)+floor(random()*3) as y, 
count(*) 
from generate_series(1,10000000) group by y order by y;
 y |  count
---+---------
 0 |  369905
 1 | 1111997
 2 | 2222763
 3 | 2593306
 4 | 2220452
 5 | 1111506
 6 |  370071
(7 rows)

Time: 18806.885 ms

Consistent distribution, but 18 seconds for 10 million rows!

The second method has a tail end of the curve that keeps going even as it tapers to 0. This uses the normal_rand function provided by postgres with arguments of quantity, median, and standard deviation.

select  x, count(*) 
from 
(select abs(ceil(normal_rand(10000000,2,1))) as x) as y 
group by x order by count;
 x |  count
---+---------
 0 |  214152
 1 | 1373200
 2 | 3414028
 3 | 3411424
 4 | 1359447
 5 |  214194
 6 |   13234
 7 |     319
 8 |       2
(9 rows)

Time: 3221.894 ms

I want the peak of the curve around 2 and 3 but for this method of Gaussian distribution I get results below 0 unless I use abs. And its fast, 3 seconds!

Ever so slightly faster intervals in postgres

When working with dates in postgres I often construct an interval like so:

> select (2 || ' days')::interval;
2 days

Which is fine! But there's an alternative that's ever so slightly faster.

> select 2 * '1 day'::interval;
2 days

The time difference can be seen over large quantities of data, like 10 million.

> select (x || ' days')::interval from generate_series(1, 10000000) as x;
...
Time: 10437.314 ms
 > select x * '1 days'::interval from generate_series(1, 10000000) as x;
...
Time: 7831.568 ms

Microbenchmarking in action! Remember, take all microbenchmarks with a grain of salt.

Non-Greedy Vim Regex

Regex is by default greedy, meaning, if you used this regex /.*, on the following line:

a123,b123,c123,d123

You'd match everything up to the last comma a123,b123,c123. If you just want everything to the first comma you need to use a non-greedy matcher. In posix regex you could modify the * operator (match 0 or more) with the ? operator, like this: /.*?,/.

Vim however is a bit weird and doesn't support making the * operator non-greedy in this manner. You can however use curly braces to tell vim to match 0 or more, but as few as possible like this: /.\{-}, which will match just a123,.

Remember, the leading curly needs to be escaped with a slash \.

See :help pattern-overview for more!

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

Capybara Find with Wait

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

Patience!

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

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

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

Ruby XOR operator

The ^ acts is a boolean XOR operator in Ruby when the arguments are boolean. It wants only one true value in an expression in order to be considered true:

true ^ false ^ false
# => true

true ^ false ^ true
# => false

Let's look at 5 trues:

true ^ true ^ true ^ true ^ true 
# => true

How is this true? Each ^ is evaluated one at a time. Since true ^ true is not exclusive, it is false. So after the first evaluation, we have:

false ^ true ^ true ^ true

# false ^ true is true

true ^ true ^ true

#true and true is false
false ^ true
# true

Using this same logic we can see why true ^ true ^ true ^ true is false.

Dealing with exit signals on Ruby

When working on CLIs it's useful to treat if the application exists. Image you have a long application and even if the user hits a <Ctrl+c> to kill the process you still want to display the results so far.

There is a Ruby Kernel method at_exit that runs the block passed to it if the current process exists. Here is an example:

# print_at_exit.rb
at_exit { puts "Come back later!" }
puts "sleeping for 5 secs"
sleep 5

If you run this file and wait it until it finishes you'll get:

ruby print_at_exit.rb                                                                                                                {130}
#=> sleeping for 5 secs
#=> 
#=> Come back later!

But now, if you run it and hit <Ctrl+c> for finishing the process earlier you'll get:

ruby print_at_exit.rb
#=> sleeping for 5 secs
^C
#=> Come back later!
#=> print_at_exit.rb:6:in `sleep': Interrupt
#=>         from print_at_exit.rb:6:in `<main>'

h/t @nikkypx

Postgres age function #postgresql

If you want to select records according to a specific interval, like Rails' ActiveSupport 1.year.ago PostgreSQL has you covered.

The age function returns an interval type and can be used in queries like so:

select * from sometbl where age(created_at) > '1 year';

By default the age function will use the current system time to calculate the age. If you want to calculate the age relative to a different time you can simply pass in another argument:

psql> select age(timestamp '2016-08-28', timestamp '1957-06-13');
           age
-------------------------
 59 years 2 mons 15 days
(1 row)

You can also use the make_interval function to create intervals using numeric parameters:

psql> select make_interval(1,2,3,4,5);
         make_interval
--------------------------------
 1 year 2 mons 25 days 05:00:00
 (1 row)

In a query it can be used like so:

select * from sometbl where age(created_at) > make_interval(1);

to select rows with created_at older than one year from now.

Read more about the age function and other cool date/time manipulations see the official documentation.

h/t Jack Christensen

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.

Elixir with macro `<-` and `=`

So Elixir with macro accepts Matching clauses <- and Bare expressions =. Both match patterns and do not leak variables assigned inside these structures.

with {:ok, width} <- Map.fetch(%{width: 10}, :width),
  do: {:ok, 2 * width}
#=> {:ok, 20}

with {:ok, width} = Map.fetch(%{width: 10}, :width),
  do: {:ok, 2 * width}
#=> {:ok, 20}

So what is the difference between these?

When a match fails, matching clauses <- returns failed result but bare expressions = raises a MatchError:

with {:ok, width} <- Map.fetch(%{height: 10}, :width),
  do: {:ok, 2 * width}
#=> :error

with {:ok, width} = Map.fetch(%{height: 10}, :width),
  do: {:ok, 2 * width}
#=> ** (MatchError) no match of right hand side value: :error

Another difference is that when guard is only available for matching clause.

with {:ok, width} when is_number(width) <- Map.fetch(%{width: 10}, :width),
  do: {:ok, 2 * width}
#=> {:ok, 20}

Verify downloaded files from the web #security

If you download a file from the web on a public WiFi and want to run on your machine you might want to check if the file has not been tampered with by a man-in-the-middle-attack or if the file host has been breached.

The easiest way to do this is to check the publised md5 or sha-1 hash for that file (you can do that via your phone if you want to be extra secure). Not every package publishes that but if they do it will be on their website usually next to the download link.

To verify the file you will need to hash the file you downloaded using openssl. For example:

 $ openssl sha1 Kali-Linux-2016.1-vm-amd64.7z
 SHA1(Kali-Linux-2016.1-vm-amd64.7z)= 2b49bf1e77c11ecb5618249ca69a46f23a6f5d2d

Which matches the site's published sha-1 hash:

kalisha

If you want to check md5, simply replace sha1 in the command with md5.

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.

Return `MatchData` with `$~`

Check out this Ruby regex:

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

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

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

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

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

h/t Brian Dunn