You’re building an app that needs to present a calendar of the current month to the user, where do you start?
You could write this implementation yourself by working out the dates and days in a month and come up with your own
algorithm to present that information but there’s an easier way. cal
is a standard program on Unix and Unix-like
operating systems that prints an ASCII calendar of the given month or year.
We can ask our operating system to run the cal program and get the output, from there we can simply display it to our user with no need to write our own algorithm or download another date library dependency.
The answer in Elixir is ports. After we open a port, the Elixir process that owns the port will recieve all sorts of
messages that we can listen for such as {port, {:data, data}}
when the program outputs some information or
{port, {:exit_status, status}}
when the program terminates.
# calendar.exs
# Start a new process and run the `cal` command with `-h` flag
# to not output highlighting of the current day. The second
# argument is a list of options used to configure the port
cal_port = Port.open({:spawn, "cal -h"}, [:binary])
# Once the port has been opened we can start a receive block
# to capture any messages/events.
receive do
{^cal_port, {:data, cal}} ->
IO.puts(cal)
end
If we run this script we will see a calendar that’s is identical to the calendar we seen from running cal
directly from
our terminal (excluding the highlighting we disabled)
Obviously we are not limited to just displaying calendars though, we can start any program installed on the host machine or maybe you have a shell script that accomplishes something already then there’s no need to re-write it again, instead we can re-use it.
Here’s a few ideas where you might want to resort to ports
ps
or top
git clone
a repositorymv
, rm
and cp
commands to manage files🖥 Software engineer. React, Elm and Elixir enthusiast 🐣