# Ruby Tuesday – Array Decomposition

Today’s Ruby Tuesday takes a look at Array Decomposition.

Ruby gives you some ability to destructure, or decompose, an `Array` into its component pieces.

Say we have an `Array` which represents a point in two-dimensional Cartesian space, we can decompose that array into its `x` and `y` coordinates, by doing an assignment of `x` and `y` to the point represented by the given `Array`, if we wrap them in parenthesis.

```(x, y) = [1, -1]
# => [1, -1]
x
# => 1
y
# => -1
```

If we want to decompose only part of the `Array`, and save off anything at the end, we can use a `*` before the last variable in the assignment.

```(_, second, *rest) = [:a, :b, :c, :d]
# => [:a, :b, :c, :d]
```

The capturing even works, if there are less items in the array than there are variables to decompose into.

```(_, second, *rest) = [:a]
# => [:a]
second
# => nil
rest
# => []
```

We can also use Array Decomposition in method arguments to decompose a passed in `Array` to individual variable for specific elements.

```def cartesian_point((x, y))
puts "x: #{x}, y: #{y}"
end
# => :cartesian_point

cartesian_point([1, -1])
# x: 1, y: -1
# => nil
```

Above I mentioned that we can capture the “rest” of the `Array` we aren’t wanting to decompose at this point by using a `*` (called the “splat” operator).

```(head, *rest) = [1, 2, 3, 4, 5]
# => [1, 2, 3, 4, 5]
# => 1
rest
# => [2, 3, 4, 5]
```

So let’s see what we get when we use the splat to capture the rest of an `Array` that is smaller than what is at the end.

```(first, *tail) = [1]
# => [1]
first
# => 1
tail
# => []
```

We get an empty list.

Let’s see what we get on the decomposition for an empty list, into the items, and a capturing “rest” variable.

```(h, *t) = []
# => []
h
# => nil
t
# => []
```

We get a `nil` as part of the binding, and we still get an empty array the “rest” of the items.

This means we can use destructing to handle recursing a list, and have a guard clause that checks if we received and empty `Array` by checking if the head of the `Array` is `nil`, and then just recurse by passing in the tail as the argument when recursing.

```def recurse_list((head, *tail))
if (head != nil)
recurse_list(tail)
else
puts "all done"
end
end
# => :recurse_list

recurse_list([1, 2, 3, 4, 5, 6, 7])
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# all done
# => nil
```

–Proctor

# Erlang Thursday – ETS Introduction, Part 2

Today’s Erlang Thursday continues the introduction to the ets module, and ETS in general.

We saw last time that ETS tables are destroyed when the parent process crashes, so the question comes, how might we be able to keep our ETS tables alive if we just “Let It Crash!”?

To solve this problem, we will take a look at the function `ets:give_away/3` and the option of specifying the `heir` at table construction.

First, we will create a function that will represent a process we can give the table ownership to. This function just does a receive and never times out.

```Fun = fun() -> receive after infinity -> ok end end.
% #Fun<erl_eval.20.54118792>
```

And now with that function, we can spawn a process to run that function.

```Process = spawn(Fun).
% <0.53.0>
```

We create a new ETS Table,

```Table = ets:new(table, []).
% 20498
```

and give it away to the process we just spawned.

```ets:give_away(Table, Process, []).
% true
```

We can look at the table info, and see the owner is now the process we spawned as the Pid for the process aligns with the Pid in the `owner` tuple in the table settings.

```ets:info(Table).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,305},
%  {owner,<0.53.0>},
%  {heir,none},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

Now that we have supposedly transferred ownership, time to crash our current process, which is the one that was the original owner before the transfer.

```1 = 2.
% ** exception error: no match of right hand side value 2
self().
% <0.58.0>
```

We check if the process we spawned is still alive, mostly out of showing that there is nothing up our sleeves.

```is_process_alive(Process).
% true
```

And let’s take a look at the “info” for the table again, and see if it is still available.

```ets:info(Table).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,305},
%  {owner,<0.53.0>},
%  {heir,none},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

It is still alive!!! We did transfer ownership, so if our process crashes the ETS table still stays alive.

Time to kill that process

```exit(Process, "Because").
% true
is_process_alive(Process).
% false
```

and watch the ETS table disappear…

```ets:info(Table).
% undefined
```

This time, let’s use the `heir` option when creating an ETS table, and take advantage of the magic of ownership transfer for an ETS table to a heir.

In this case, the shell will be the heir when the owning process dies.

```TableWithHeir = ets:new(table, [{heir, self(), "something went wrong"}]).
% 24594
```

We create a new process, and assign ownership of the ETS table to the new process.

```Process2 = spawn(Fun).
% <0.71.0>
ets:give_away(TableWithHeir, Process2, []).
% true
```

We then look at the info for the table, and we can see both the owner is the new process, and the heir is our current process.

```self().
% <0.58.0>
ets:info(TableWithHeir).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,349},
%  {owner,<0.71.0>},
%  {heir,<0.58.0>},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

Time to kill the owning process again…

```exit(Process2, "Because").
% true
is_process_alive(Process2).
% false
```

And if we inspect the table info again, we can see the current process is now both the owner and the heir.

```ets:info(TableWithHeir).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,349},
%  {owner,<0.58.0>},
%  {heir,<0.58.0>},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

We spawn up a new process, and we give the table to that new process.

```Process3 = spawn(Fun).
% <0.78.0>
ets:give_away(TableWithHeir, Process3, []).
% true
```

The owner now becomes that new process, and our current process is still the heir.

```ets:info(TableWithHeir).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,349},
%  {owner,<0.78.0>},
%  {heir,<0.58.0>},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

So by taking advantage of the ability to specify a heir, and using `ets:give_away/3`, we can help keep the ETS table alive.

One way this might be taken advantage of is that we have a supervisor create a “heir” process, and then create the child process that would own the ETS table, and if the child dies, it can then transfer ownership back to the heir process until the new “owning” process can be restarted, and then the heir process can then transfer ownership of the ETS table to the “newly restarted” process.

–Proctor

# Ruby Tuesday – SSL Version In Ruby

Today’s Ruby Tuesday takes a look at the OpenSSL::SSL::SSLContext#ssl_version.

At work today, I was pulled into a bit of a “fire”, where I was told that one of the sets of services our app at work depends on is going to be removing support for all but TLS 1.2.

Just doing a basic `Net::HTTP.get` did not get us a result back, and we first had to figure out how to get TLS 1.2 as something that Ruby as the client would say it supports.

Before we can start testing any of this, we need to require `openssl` and `net/http`.

```require 'openssl'
# => true
require 'net/http'
# => true
```

It turns out when you don’t specify a version the default version is SSLv23, which can be found by looking at `DEFAULT_PARAMS` on the `SSLContext`.

```OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version]
=> "SSLv23"
```

Since TLSv1.2, is a “higher” version than SSLv23, we were getting errors back because we a connection using TLSv1.2 would never be negotiated.

To get the ability to support TLS generically, instead of just hardcoding a specific version, e.g. `TLSv1`, or `TLSv1_2`, the `ssl_version` needs to be set to `nil` to tell Ruby’s OpenSSL components to use TLS instead of SSL.

This opened up the question of if we set OpenSSL to be TLS instead of SSL, would the TLS Protocol negotiate down to SSL if we happen to have an endpoint we need to talk to that doesn’t currently support TLS, but only SSL.

Playing around with `Net::HTTP.start` I was able to play with sending HTTPs requests using different settings for the `ssl_version`.

As I was also testing against a local instance of nginx that would only support SSLv3 using a self-signed certificate, I had the `veryfy_mode` to `VERIFY_NONE` for testing. Note that I do NOT recommend this for real use cases.

The first helper method I created doesn’t specify a `ssl_version` option, so it just uses the default `ssl_version` setting.

```def test_url_no_version(url)
Net::HTTP.start(url.hostname, nil,
use_ssl: url.scheme == "https",
verify_mode: OpenSSL::SSL::VERIFY_NONE ) do |http|
response = http.request(Net::HTTP::Get.new(url))
puts response.inspect
response
end
end
# => :test_url_no_version
```

The the next helper method I created sets the `ssl_version` option to `nil` to allow it to use TLS instead of SSL.

```def test_url_ssl_version_is_nil(url)
Net::HTTP.start(url.hostname, nil,
use_ssl: url.scheme == "https",
verify_mode: OpenSSL::SSL::VERIFY_NONE,
ssl_version: nil ) do |http|
response = http.request(Net::HTTP::Get.new(url))
puts response.inspect
response
end
end
# => :test_url
```

The the last helper method I created sets the `ssl_version` option to `:SSLv3`, which is the only version the webserver is setup to handle.

```def test_url_ssl3(url)
Net::HTTP.start(url.hostname, nil,
use_ssl: url.scheme == "https",
verify_mode: OpenSSL::SSL::VERIFY_NONE,
ssl_version: :SSLv3 ) do |http|
response = http.request(Net::HTTP::Get.new(url))
puts response.inspect
response
end
end
# => :test_url_ssl3
```

Now that we have these, we can test the results of asking the test webserver for a request and see what happens. We will also use Google as a baseline to compare against.

First we will test the verion where the `ssl_version` is set to `nil`. This would tell us if it would fall back to try a SSL variant.

```test_url_ssl_version_is_nil(URI("https://www.google.com"))
# #<Net::HTTPOK 200 OK readbody=true>
# => #<Net::HTTPOK 200 OK readbody=true>
test_url_ssl_version_is_nil(URI("https://localhost/index.html"))
# OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unsupported protocol
# from /Users/proctor/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/net/http.rb:923:in `connect'
```

Google returns successfully, but the local test doesn’t so it doesn’t look to fall back to SSL from TLS.

Next we try with the default setting for `ssl_version`.

```test_url_no_version(URI("https://www.google.com"))
# #<Net::HTTPOK 200 OK readbody=true>
# => #<Net::HTTPOK 200 OK readbody=true>
test_url_no_version(URI("https://localhost/index.html"))
# OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unsupported protocol
# from /Users/proctor/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/net/http.rb:923:in `connect'
```

Google still returns successfully, but the local test case still doesn’t work.

Finally we will test with specifying SSL v3 specifically.

```test_url_ssl3(URI("https://www.google.com"))
# #<Net::HTTPOK 200 OK readbody=true>
# => #<Net::HTTPOK 200 OK readbody=true>
test_url_ssl3(URI("https://localhost/index.html"))
# #<Net::HTTPOK 200 OK readbody=true>
# => #<Net::HTTPOK 200 OK readbody=true>
```

And for this, Google and the local test both work. So we have shown that with the right ssl version specified, we do get a response back from our local test server, but the fallback from TLS to SSL doesn’t happen.

–Proctor

# Erlang Thursday – ETS Introduction, Part 1

Today’s Erlang Thursday starts the beginning of an intro to the ets module, and ETS in general.

ETS stands for Erlang Term Storage, and is a in-memory store for Erlang terms, a.k.a pieces of an Erlang data type, that provides constant access time to the data stored.

ETS can be thought of as a key/value store style storage, and it uses the concept of tables as the way of grouping together data.

One of the first things that is useful to know is that ETS tables are created by a process which, unless transfered to another process, is the owner of the table.

When the owner dies, the table gets deleted, and is no longer accessible.

Let’s see what this would look like.

First, after starting a new Erlang shell, we will check the PID (process identifier) of the shell we are in.

```self().
% <0.34.0>
```

We then will create a new ETS table. We will be going into future details about the various ways new tables can be created in future posts, so for now, we will just create a new table by only specifying a name and empty list of options.

```TableId = ets:new(table, []).
% 20496
```

Capturing table id, we will take a look at the info that ETS knows about that table with `ets:info/1`.

```ets:info(TableId).
%  {write_concurrency,false},
%  {compressed,false},
%  {memory,305},
%  {owner,<0.34.0>},
%  {heir,none},
%  {name,table},
%  {size,0},
%  {node,nonode@nohost},
%  {named_table,false},
%  {type,set},
%  {keypos,1},
%  {protection,protected}]
```

Time to cause the owning process to crash. In this case we’ll do a bad pattern match to cause a bad match exception.

```1 = 2.
% ** exception error: no match of right hand side value 2
```

And let’s check the PID of the process to double check that the shell has indeed started a new process for us to run in.

```self().
% <0.40.0>
```

And yes, the PID `self()` returned is different than the PID we got when we called `self()` the first time.

Time to look at the info for the table we created earlier again and see what we get.

```ets:info(TableId).
% undefined
```

`undefined`. So we no longer have any table found by ETS for that table id.

We take a secondary look using `ets:all/0` to see if we can see if it might be floating around somewhere still but the call to `ets:info/1` is just not returning for the table id.

```ets:all().
%  inet_cache,inet_db,global_pid_ids,global_pid_names,
%  global_names_ext,global_names,global_locks,4098,1,ac_tab]
```

Doesn’t look like it, so let’s create another table with the same table name as before.

```Table2Id = ets:new(table, []).
% 24592
```

That succeeds and doesn’t complain about trying to create a table with the same name as an existing table.

We will call `ets:all/0` again, and we can see there is an item in the list with the id that was returned from `ets:new/2`.

```ets:all().
%  inet_cache,inet_db,global_pid_ids,global_pid_names,
%  global_names_ext,global_names,global_locks,4098,1,ac_tab]
```

Time to crash the process again.

```1 = 2.
% ** exception error: no match of right hand side value 2
```

We note that we do have a new PID again.

```self().
% <0.47.0>
```

And if we call `ets:all/0` one more time, we can see that the table identifier that was previously in the list has gone away.

```ets:all().
%  inet_cache,inet_db,global_pid_ids,global_pid_names,
%  global_names_ext,global_names,global_locks,4098,1,ac_tab]
```

So with this initial look at ETS, we have demonstrated an owning process crash does remove the table, and we have also gotten an preview of a couple of the functions in the `ets` module, specifically `ets:new/2`, `ets:info/1`, and `ets:all/0`.

We will continue looking at the overview of ETS for a few posts, while doing some cursory coverage of some of the functions in the `ets` module, and after that, we will then start to get into the specifics of the different functions in the `ets` module.

–Proctor

# Ruby Tuesday – Symbol#to_proc

Today’s Ruby Tuesday is on Symbol#to_proc.

`Symbol#to_proc` returns a `Proc` object which corresponds to the method represented by the symbol it is called on.

First, we will create a new method `foo` which just puts the string `Foo` to output.

```def foo
puts "Foo"
end
# => :foo
```

Now let’s call `Symbol#to_proc` on a couple of different symbols, and see what their return values are.

```:foo.to_proc
# => #<Proc:0x007ff08395d9b0>
:to_s.to_proc
# => #<Proc:0x007ff0829f42a8>
:keys.to_proc
# => #<Proc:0x007ff0828280f0>
```

And we will also capture the results of calling `to_proc` on the symbol `:to_s`, so that we can be assured that it is the same `Proc` object later on.

```to_s_proc = :to_s.to_proc
# => #<Proc:0x007ff0829f42a8>
```

Now that we have seen that `Proc`s are being returned, it’s time to call those `Proc`s to see how they behave.

```:to_s.to_proc.call(1)
# => "1"
:foo.to_proc.call(1)
# Foo
# => nil
:keys.to_proc.call({:a => 1, :b => 2, :c => 3})
# => [:a, :b, :c]
:foo.to_proc.call()
# ArgumentError: no receiver given
# from (pry):40:in `call'
:foo.to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (2 for 0)
# from (pry):1:in `foo'
```

When we call a `Proc` generated in this way at the Ruby shell, the first argument is the context for what the `Proc` will be called against.

If we pass no arguments, we get an error of `no receiver given`, telling us that the `Proc` doesn’t have anything to call the method on.

```:foo.to_proc.call()
# ArgumentError: no receiver given
# from (pry):40:in `call'
```

And if we pass in extra arguments to a `Proc` that was generated from calling `Symbol#to_proc`, it will error out as it expects the right number of arguments to be passed to the `Proc`.

```:foo.to_proc.call(1, 2, 3)
# ArgumentError: wrong number of arguments (2 for 0)
# from (pry):1:in `foo'
```

And finally, we will call the `Proc` we captured in a variable, to show that the same `Proc` will operate against multiple objects of different types.

```to_s_proc.call(1)
# => "1"
to_s_proc.call({:a => 1, :b => 2, :c => 3})
# => "{:a=>1, :b=>2, :c=>3}"
```

So we can see that the `Proc` we got from calling `:to_s.to_proc` will work and call `to_s` on both and integer and a `Hash`.

–Proctor

# Erlang Thursday – digraph:del_path/3

Today’s Erlang Thursday is on digraph:del_path/3.

We will continue working with the same graph we started with in the previous post on digraph:get_path/3.

```Graph = digraph:new().
% {digraph,20498,24595,28692,true}
% ['\$v'|0]
% ['\$v'|1]
% ['\$v'|2]
% ['\$v'|3]
E1 = digraph:add_edge(Graph, V1, V2).
% ['\$e'|0]
E2 = digraph:add_edge(Graph, V2, V3).
% ['\$e'|1]
E3 = digraph:add_edge(Graph, V3, V4).
% ['\$e'|2]
E4 = digraph:add_edge(Graph, V2, V4).
% ['\$e'|3]
E5 = digraph:add_edge(Graph, V4, V1).
% ['\$e'|4]
```

`digraph:del_path/3` takes three arguments, a Graph, a source vertex, and a destination vertex, and removes all edges in a each path in the graph from the source vertex to the destination vertex, until no path exist between the source and destination vertices.

The return value of `digraph:del_path/3` is always a return value of `true`.

Looking at the picture of the graph above as reference, we are going to call `digraph:del_path/3` for the graph with a source vertex of V1, and a destination vertex of V4.

```digraph:del_path(Graph, V1, V4).
% true
digraph:vertices(Graph).
% [['\$v'|2],['\$v'|1],['\$v'|0],['\$v'|3]]
digraph:edges(Graph).
% [['\$e'|1],['\$e'|2],['\$e'|4]]
```

Translating the edge names, we see that the edge from V1 to V2 has been removed, as well as the edge from V2 to V4 has been removed.

So how did Erlang come up with this result?

This puzzled me at first, as it wasn’t one of the two scenarios I was expecting to see, which were either: remove all edges but the edge from V4 to V1, or remove only the edge from V1 to V2.

I then opened the Erlang source code on Github for digraph module to clarify my thinking, and looking at the code it then made sense what was happening.

First `digraph:del_path/3` calls `digraph:get_path/3`, and removes all edges in that path, and then recurses until no path is found.

This is when it clicked as to why Erlang was removing only those edges.

If we call `digraph:get_path/3` on a fresh version of the graph, we see that it returns the path of `V1 -> V2 -> V4`.

```digraph:get_path(Graph, V1, V4).
[['\$v'|0],['\$v'|1],['\$v'|3]]
```

Erlang then removes the edges in that path, and the will call `digraph:del_path/3`, which calls `digraph:get_path/3` again, but as we removed the edge between V1 and V2, no path is found so the process is finished.

This is why we see more edges removed if we reset the Graph again (by exiting the shell and recreating it from scratch by pasting the initialization into the shell), and call `digraph:del_path/3` between V2 and V4.

```digraph:del_path(Graph, V2, V4).
% true
digraph:edges(Graph).
% [['\$e'|0],['\$e'|4]]
```

This case there are the paths `V2 -> V4` and `V2 -> V3 -> V4`, and if we remove the path `V2 -> V4`, the removal of all the edges associated with that path doesn’t break the path of `V2 -> V3 -> V4`, so it can remove all edges in that path as well.

So we have a win in the case where the documentation wasn’t quite as clear as it could be, but having the Erlang standard library be open source gets us a win because we can always go in and check out what the code is really doing.

–Proctor

# Ruby Tuesday – Symbol#id2name

Today’s Ruby Tuesday is on Symbol#id2name.

`Symbol#id2name` returns the string value for a given symbol that is the name of the symbol.

```:foo.id2name
# => "foo"
:'HelloWorld'.id2name
# => "HelloWorld"
:nil.id2name
# => "nil"
:''.id2name
# => ""
```

If we scroll down the documentation page for `Symbol` down to Symbol#to_s, we can see it is using `id2name` in the example.

So let’s see if we can quickly notice a difference in what is returned.

```:foo.to_s
# => "foo"
:''.to_s
# => ""
:nil.to_s
# => "nil"
```

We can see the behavior appears to indeed be the same, so we will dig a little deeper.

If you go to the documentation page for both methods, and then toggle the source for both of the methods, you can see they both use the underlying procedure `rb_sym_to_s`, and are infact aliases for each other.

–Proctor

# Erlang Thursday – digraph:get_cycle/2

Today’s Erlang Thursday is on digraph:get_cycle/2.

We will continue working with the graph from the previous post on digraph:get_path/3.

```Graph = digraph:new().
% {digraph,20498,24595,28692,true}
% ['\$v'|0]
% ['\$v'|1]
% ['\$v'|2]
% ['\$v'|3]
E1 = digraph:add_edge(Graph, V1, V2).
% ['\$e'|0]
E2 = digraph:add_edge(Graph, V2, V3).
% ['\$e'|1]
E3 = digraph:add_edge(Graph, V3, V4).
% ['\$e'|2]
E4 = digraph:add_edge(Graph, V2, V4).
% ['\$e'|3]
E5 = digraph:add_edge(Graph, V4, V1).
% ['\$e'|4]
```

`digraph:get_cycle/2` takes a graph `G`, and an vertex `V`, and tries to find a path that creates a cycle between the vertex `V` in graph `G`.

```digraph:get_cycle(Graph, V1).
% [['\$v'|0],['\$v'|1],['\$v'|3],['\$v'|0]]
digraph:get_cycle(Graph, V2).
% [['\$v'|1],['\$v'|3],['\$v'|0],['\$v'|1]]
```

Next, we add a new vertex `V5`, and a new edge originating from `V4` and ending on `V5`

We then call `digraph:get_cycle/2` on V5, and we get back a `false` as no cyle exists in the graph with vertex `V5` in it.

```V5 = digraph:add_vertex(Graph).
% ['\$v'|4]
E6 = digraph:add_edge(Graph, V4, V5).
% ['\$e'|5]
digraph:get_cycle(Graph, V5).
% false
```

The `digraph` module also contains the function digraph:get_short_cycle/2.

`digraph:get_short_cycle/2` attempts to find the shortest cycle in the graph `G` for vertex `V`.

The documentation for `digraph:get_short_cycle/2` exact phrasing is:

Tries to find an as short as possible simple cycle through the vertex V of the digraph G.

So depending on how you read that, the shortest cycle might not be guaranteed to be returned, but simply a shorter cycle, which may depend on the overall size and complexity of the graph.

```digraph:get_short_cycle(Graph, V1).
% [['\$v'|0],['\$v'|1],['\$v'|3],['\$v'|0]]
digraph:get_short_cycle(Graph, V5).
% false
```

–Proctor

# Ruby Tuesday – Hash#fetch

Today’s Ruby Tuesday is on Hash#fetch.

`Hash#fetch` is one of those methods that would have to go in my Top 10 of most underutilized methods in Ruby.

Why would `Hash#fetch` make that list? Because it makes explicit the results of a key lookup in a Hash.

If we have a `Hash` constructed using a hash literal, and do a key lookup using the square brackets, it will return a `nil` when a key is not found, as `nil` is the default default-value for `Hash`es.

```hash1 = {:a => 1, :b => 2, :c => 3}
# => {:a=>1, :b=>2, :c=>3}
hash1[:a]
# => 1
hash1[:d]
# => nil
```

You might be thinking, “That’s not so bad, I can just check for `nil`s”.

What happens when there is a key that references `nil`? Now you can’t know if `nil` was in there because it was “valid”, or just returned.

```hash2 = {:a => 1, :b => 2, :c => 3, :d => nil}
# => {:a=>1, :b=>2, :c=>3, :d=>nil}
hash2[:d]
# => nil
```

Or what happens when you get a Hash that was not created with a Hash literal?

```hash3 = Hash.new {|hash, key| "foo"}
# => {}
hash4 = Hash.new("foo")
# => {}
hash3[:a]
# => "foo"
hash4[:a]
# => "foo"
```

Oops. We no longer get a `nil` back that we can check against.

This is where `Hash#fetch` becomes nice and explicit.

If we call `Hash#fetch` and no key is found, it will raise an `key not found` exception.

```hash2.fetch(:d)
# => nil
hash1.fetch(:d)
# from (pry):8:in `fetch'
```

Why is this nice? Well, it means we encountered and error, and we stop execution at the point of the error, instead of propagating `nil`s throughout the code base to crash at some later point.

If we don’t want an exception, we can also pass in a default value to `Hash#fetch` allowing us to control the default value when a key is not found.

```hash1.fetch(:d, :key_not_found)
# => :key_not_found
hash2.fetch(:d, :key_not_found)
# => nil
hash3.fetch(:a, :key_not_found)
# => :key_not_found
hash4.fetch(:a, :key_not_found)
# => :key_not_found
```

It even works when the `Hash` `fetch` is being called on specifies different default behavior.

Even when that default behavior would try to add the key into the `Hash` with a default value.

```hash5 = Hash.new {|hash, key| hash[key] = "foo"}
# => {}
hash5.fetch(:d)
# from (pry):43:in `fetch'
hash5.fetch(:d, "bar")
# => "bar"
```

`Hash#fetch` can also take a block that will be called with the key as an argument, when the key is not found in the `Hash`.

```hash1.fetch(:d) do |key|
puts "no key found for key: `#{key}`"
:no_key_found
end
# no key found for key: `d`
# => :no_key_found
```

I encourage you to play with it, and see if it doesn’t start to creep up into your list of favorite methods that are underutilized.

–Proctor

# Erlang Thursday – digraph:in_neighbors/2

Today’s Erlang Thursday is on digraph:in_neighbors/2.

`digraph:in_neighbors/2` takes a graph `G`, and a vertex `V`, and will return a list of all the vertices that have edges originating from them that are directed toward the vertex `V`.

We will continue working with the graph from last week’s post on digraph:get_path/3.

```Graph = digraph:new().
% {digraph,20498,24595,28692,true}
% ['\$v'|0]
% ['\$v'|1]
% ['\$v'|2]
% ['\$v'|3]
E1 = digraph:add_edge(Graph, V1, V2).
% ['\$e'|0]
E2 = digraph:add_edge(Graph, V2, V3).
% ['\$e'|1]
E3 = digraph:add_edge(Graph, V3, V4).
% ['\$e'|2]
E4 = digraph:add_edge(Graph, V2, V4).
% ['\$e'|3]
E5 = digraph:add_edge(Graph, V4, V1).
% ['\$e'|4]
```

With that graph setup again, we can now find the `in_neighbors` of different vertices in our graph.

```digraph:in_neighbours(Graph, V4).
% [['\$v'|1],['\$v'|2]]
digraph:in_neighbours(Graph, V1).
% [['\$v'|3]]
digraph:in_neighbours(Graph, V2).
% [['\$v'|0]]
```

So for vertex `V4` we see the return value of `[['\$v'|1],['\$v'|2]]`, which are the vertices `V2` and `V3`. For `V1` we have an inbound neighbor of `V4`, and for `V2` we have the inbound neighbor of `V1`.

### digraph:out_neighbors/2

The `digraph` module also contains the function digraph:out_neighbors/2, which returns a list of the vertices that a the given vertex “points to” with its edges in the directed graph.

```digraph:out_neighbours(Graph, V2).
% [['\$v'|3],['\$v'|2]]
digraph:out_neighbours(Graph, V4).
% [['\$v'|0]]
digraph:out_neighbours(Graph, V1).
% [['\$v'|1]]
```

We can see from the picture of our graph that `V2` has edges that “point to” the vertices `V3` and `V4`, and if we look at the result of `digraph:out_neighbors/2`, we get the result of the vertices `V3` and `V4`.

In this case we get the list of vertices where `V4` is first and `V3` is second, but that may not be the case, as the documentation states that the the edges are “in some unspecified order”, which holds true of `digraph:in_neighbors/2` as well.

–Proctor