Now let’s continue down our data-transformation chain. Having parsed our arguments, we need to transform them by fetching data from GitHub. So we’ll extend our run function to call a process function, passing it the value returned from the parse_args function. We could have written this:
| process(parse_args(argv)) |
But to understand this code, you have to read it right to left. I prefer to make the chain more explicit using the Elixir pipe operator:
| def run(argv) do |
| argv |
| |> parse_args |
| |> process |
| end |
We need two variants of the process function. One handles the case where the user asked for help and parse_args returned :help. The other handles the case where a user, a project, and a count are returned.
| def process(:help) do |
| IO.puts """ |
| usage: issues <user> <project> [ count | #{@default_count} ] |
| """ |
| System.halt(0) |
| end |
| |
| def process({user, project, _count}) do |
| Issues.GithubIssues.fetch(user, project) |
| end |
We can use mix to run our function. Let’s first see if help gets displayed.
| $ mix run -e 'Issues.CLI.run(["-h"])' |
| usage: issues <user> <project> [ count | 4 ] |
You pass mix run an Elixir expression, which gets evaluated in the context of your application. Mix will recompile your application, as it is out of date, before executing the expression.
If we pass it user and project names, however, it’ll blow up because we haven’t written that code yet.
| % mix run -e 'Issues.CLI.run(["elixir-lang", "elixir"])' |
| ** (UndefinedFunctionError) undefined function: Issues.GithubIssues.fetch/2 |
| GithubIssues.fetch("elixir-lang", "elixir") |
Let’s write that code now. Our program will act as an HTTP client, accessing GitHub through its web API. So, it looks like we’ll need an external library.