1. Running Multiple Mix Tasks
mix do deps.get,compile
You can run multiple tasks by separating them with a comma ,
.
However, you can also create aliases in your mix project in a file called
mix.exs
.
The project definition looks like the following way when you create one using
a mix
tool.
def project do
[app: :proect_name,
version: "0.1.0",
elixir: "~> 1.4-rc",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps()]
end
You are also allowed to add some extra fields
Here you have to add the aliases
field.
[
aliases: aliases()
]
Don’t forget to add ,
at the end when you add this in the middle of list
.
The aliases()
should return the key-value
list.
defp aliases do
[
"ecto.setup": ["ecto.create", "ecto.migrate", "ecto.seed"]
]
end
So, whenever you run the mix ecto.setup
the three tasks ecto.create
,
ecto.migrate
, and ecto.seed
will run one after the other.
You can also add them directly as following unlike I did with private function.
def project do
[
aliases: ["ecto.setup": ["ecto.create", "ecto.migrate", "ecto.seed"]
]
end
2. Accessing the Documentation
Elixir
stores the documentation inside the bytecode in a memory
. You can access the documentation with the help of Code.get_docs/2
function.
This means, the documentation accessed when it is required but not when it
is loaded in the virtual machine like iex
Suppose, you defined a module in memory like ones you defined in IEx
, cannot
have their documentation accessed as they do not have their bytecode written to disk.
Let us check this;
Create a module with name test.ex
with the following code. You can copy and paste it.
defmodule Test do
@moduledoc """
This is the test module docs
"""
@doc """
This is the documentation of hello function
"""
def hello do
IO.puts "hello"
end
end
Now stay in the directory where your file exists and run the command
iex test.ex
Now you can access the function definitions but not the documentation.
iex> Test.hello
hello
:ok
That means the code is compiled but documentation is not stored in the memory. So, you cannot access the docs. Lets check that…
iex> Code.get_docs Hello,:moduledoc
nil
You will see the output as nil
when you are trying to access the docs of the module you have created so far.
This is because the bytecode
is not available in the disk.
In simple way beam
file is not present. Lets do that…
Press Ctrl+C twice so you will come out of the shell and this time you run the command as
$ elixirc test.ex
After running the command, you will see a file with name Elixir.Test.beam
.
Now the bytecode for the module Test
is available in memory. Now you can access the documentation as follows…
iex> Code.get_docs Test,:moduledoc
{3, "This is the test module docs\n"}
The output is a tuple with two elements. The first element is the line number of the documentation it starts and the second element is the actual documentation in the binary form.
You can read more about this function here
3. Verbose Testing
When you go with mix test
it will run all the tests defined and gives you the time of testing.
However, you can see more verbose output like which test you are running with
the --trace
option like following;
mix test --trace
It will list out the all tests with names you defined as test "test_string
"
here test_string
is the name of the test.
4. Dynamic Function Name in Elixir Macro
defmacro gen_function(fun_name) do
quote do
def unquote(:"#{fun_name}")() do
# your code...
end
end
end
To be simple the name of the function should be an atom
instead of binary.
5. Run Shell Commands in Elixir
System.cmd(command,args,options \\[])
Executes the given command with args.
- command is expected to be an executable available in
PATH
unless an absolute path is given. - args must be a list of binaries which the executable will receive as its arguments as is. This means that:
Examples
iex> System.cmd "echo", ["hello"]
{"hello\n", 0}
iex> System.cmd "echo", ["hello"],into: []
{["hello\n"], 0}
Get help from iex
with h System.cmd
Checkout the documentation about System for more information and
also check Erlang os Module.
6. Printing List as List without ASCII-Encoding
You know that when the list contains all the numbers as ASCII values, it will list out those values instead of the original numbers. Lets check that…
iex> IO.inspect [97,98]
'ab'
'ab
The code point of a
is 97
and b
is 98
hence it is listing out
them as char_list
. However you can tell the IO.inspect
to list them as
list itself with option char_lists: :as_list
.
iex> IO.inspect [97,98],charlists: :as_lists
[97, 98]
'ab'
Open iex
and type h Inspect.Opts
, you will see that Elixir does this kind of
thing with other values as well, specifically structs and binaries.
7. Accessing file name and line number etc…
defmacro __ENV__()
This macro gives the current environment information. You can get the
information like current filename
line
function
and others…
iex(4)> __ENV__.file
"iex"
iex(5)> __ENV__.line
5
You can also use them for debugging purpose in your lines of code.
8. Creating Manual
You can create the pid manually in Elixir with pid
function. This comes with two flavors.
def pid(string)
Creates a PID with 3
non negative integers passed as arguments to the
function.
iex> pid(0, 21, 32)
#PID<0.21.32>
Why do you create the pids manually?
Suppose you are writing a library and you want to test one of your functions for the type pid, then you can create one and test over it.
You cannot create the pid like assigning pid = #PID<0.21.32>
because # is considered as comment here.
iex(6)> pid = #PID<0.21.32>
...(6)>
When you do like above, iex shell just wait for more input as
#PID<0.21.32>
is treated as comment.
Now you enter another data to complete the expression. The entered value is the value of the pid. Lets check that…
iex(6)> pid = #PID<0.21.32> # here expression is not complete
...(6)> 23 # here we are giving the value 23
23 # expression is complete
iex(7)> pid
23
9. Replacing the String with global option
The String.replace
function will replace the given the pattern with replacing pattern. By default, it replaces all the occurrences of the pattern.
Lets check that…
iex(1)> str = "[email protected], [email protected]"
"[email protected], [email protected]"
iex(2)> String.replace str,"@","#"
"hello#hi.com, blackode#medium.com
The
String.replace str,"@","#"
is same as
String.replace str,"@","#",global: true
But, if you want to replace only the first occurrence of the pattern, you need to pass the
option global: false
. So, it replaces only the first occurrence of @
.
Lets check that…
iex(3)> String.replace str,"@","#",global: false
"hello#hi.com, [email protected]"
Here only first @
is replaced with #
10.Memory Usage
You can check the memory usage with :erlang.memory
iex(1)> :erlang.memory
[total: 16221568, processes: 4366128, processes_used: 4364992, system: 11855440,
atom: 264529, atom_used: 250685, binary: 151192, code: 5845369, ets: 331768]
However, you can pass option like :erlang.memory :atom
to get the memory usage of atoms.
iex> :erlang.memory :atom
264529
Check out the GitHub repository on Killer Elixir Tips
Glad if you can contribute with a ★