官术网_书友最值得收藏!

Erlang interoperability

As we stated at the beginning of this chapter, Elixir targets the Erlang runtime. Elixir is compiled to byte-code that can run on an Erlang VM (or BEAM), and Erlang libraries can be used in your Elixir projects (and vice versa). The philosophy in the Elixir community is to not reinvent the wheel and directly use Erlang libraries when appropriate. The creation of Elixir libraries that simply wrap an underlying Erlang library is discouraged, as you can directly call an Erlang library from your Elixir code.

We can take advantage not only of Erlang libraries, but also of their tooling. For instance, Erlang ships with a tool called Observer, which allows you to monitor your server and provides you with tons of useful information about the Erlang VM, such as the running processes or dynamic charts of load. We'll explore this tool in greater detail in Chapter 11Keeping an Eye on Your Processes, when we talk about monitoring.

To utilize an Erlang library, you write its name as an atom and then call functions on it. Elixir doesn't have a Math module, so when more advanced mathematical operators are needed, it's common to call the math Erlang library. Let's use this library to calculate the natural logarithm of 10:

iex> :math.log(10)
2.302585092994046
You can check out Erlang's standard libraries at http://erlang.org/doc/apps/stdlib/index.html.

When we introduced the data types in Elixir, we mentioned the Port type, which is a reference to a resource used by the Erlang VM to interact with external resources. Let's now see how we can use them to interact with an operating system process. To interact with ports, we use functions from the Port module. In the following example, we'll use the whoami UNIX command, which prints the username associated with the current user. To do that, we open a port and provide the name of the executable we want to run:

iex> port = Port.open({:spawn, "whoami"}, [:binary])
#Port<0.3730>

We passed the [:binary] option so that we get our result as a binary instead of a list of bytes. We now use the IEx flush() helper to print the messages received by the port:

iex> flush()
{#Port<0.3731>, {:data, "dcaixinha\n"}}
:ok

As our operating system process died after returning its result, the port is also closed. If this was not the case, we could use the Port.close/1 function to explicitly close the port. Also note that this was a very simple example. You can have more complex interactions by using the Kernel.send/2 function to dynamically send messages (that contain commands) to your port. In the official documentation for ports (which is available at https://hexdocs.pm/elixir/Port.html), you can see how this can be achieved.

If all we're interested in is running an operating-system command and getting its result back, we can use the System.cmd/3 function, which is an abstraction on top of ports that allows us to achieve this effortlessly.

主站蜘蛛池模板: 鹤山市| 邹城市| 中江县| 凤冈县| 青州市| 乐都县| 阜阳市| 应城市| 民丰县| 仙居县| 临朐县| 镇平县| 四会市| 邯郸县| 涞源县| 阳泉市| 兴安盟| 普定县| 云安县| 略阳县| 水富县| 山阳县| 丹棱县| 井冈山市| 新干县| 和田县| 德庆县| 大同县| 雷州市| 商都县| 灵台县| 南岸区| 墨脱县| 北票市| 盐亭县| 吉林省| 原阳县| 白朗县| 万荣县| 信阳市| 新绛县|