This commit adds the System.fetch_env/1 and System.fetch_env!/1
functions as per the discussion in
https://groups.google.com/forum/#!topic/elixir-lang-core/QGxEibK4y7Q.
I chose to keep using the same underlying implementation for fetch_env/1
as the one for get_env/1 because the number of lines would have been the
same but we would have added one function call.
And vice-versa.
Overriding a macro as a function (and vice-versa) might produce
undesired effects.
For example, it's not clear if the following code should or
should not raise:
defmodule Foo do
def foo, do: bar()
defmacro bar, do: :ok
defoverridable bar: 0
def bar, do: :ok
end
On top of that, `super` does not currently work for such cases.
Elixir v1.6 introduced Kernel.ParallelCompiler.async/1, which
allows a file to spawn other processes to speed up compilation.
However, the compiler implementation assumed that if the number
of waiting processes were equal to the number of queued files,
it was a deadlock. However, with the introduction of async,
this is not necessarily true, as the async entries can be waiting
too. So this commit changes the compiler to track all spawned
entries.
Closes#8744.
For this module:
defmodule M do
import Record
@type t :: record(:r, foo: atom(), bar: integer())
defrecord :r, [:foo, :bar]
end
`@type t` is defined as the following:
Before this patch:
@type t() :: {:r, atom(), integer()}
After this patch:
@type t() :: {:r, foo :: atom(), bar :: integer()}
This is similar to loading record definition in Erlang shell:
1> rr(file).
[file_descriptor,file_info]
2> rl(file_descriptor).
-record(file_descriptor,{module :: module(),data :: term()}).
ok
We check for >= 5000 (us) instead of >= 10000 (us)
because the resolution on Windows system is not high
enough and we would get a difference of 9000 from
time to time. So a value halfway is good enough.
Defining __MODULE__.Something in a nested defmodule would fail
to compile. This commit address this:
defmodule Foo do
defmodule __MODULE__.Bar do
__MODULE__ == Elixir.Foo.Bar
end
end
Since `__MODULE__` expands to a fully qualified name `Elixir.Foo`,
the nested module must then be `Elixir.Foo.Bar`. This commit also
fixes an alias leakage that would happen under such scenarios.
Another possible interpretation would be for it to return `Foo.Foo.Bar`.
However, that would mean we would not be able to access the module
right below its definition using `__MODULE__.Bar`, which means its
`Foo.Foo.Bar` would be the incorrect choice.
This commit adds 6 new options to elixir CLI to aid releases:
* `--pipe-to PIPEDIR LOGDIR` - invokes run_erl with daemon pipe and logs (only on Unix-like systems)
* `--rpc-eval NODE COMMAND` - evaluates the given expression on the given node
* `--boot FILE`, `--boot-var VAR VALUE`, `--erl-config FILE` and `--vm-args FILE` - which are equivalent to Erlang's `-boot`, `-boot_var`, `-config` and `-args_file`
We have also rewritten the CLI to only pass Elixir options to Kernel.CLI.
Non-printable arguments were killing the StringIO process, which
was killing the Logger handler associated to it. That was
causing some errors when users were running their test suites
with `capture_log: true`, because the proxy (Logger handler) was
not there when ExUnit.CaptureLog was trying to remove it.
Binary/bitstring matching allows to dynamically define the
`size` of the binary in certain conditions:
* if the `size` variable is defined prior to the pattern
match:
iex> size = 8
iex> <<a::size(size), rest::binary>> = "hello"
iex> a
104
* if the `size` variable is matched within the same
binary/bitstring match, prior to its use:
iex> <<name_size::size(8), name::binary-size(name_size), _rest::binary>> = <<5, "Frank the Walrus">>
iex> name
"Frank"
Other cases are considered illegal patterns, for example:
{name_size, <<name::binary-size(name_size), _rest::binary>>} = {5, "Frank the Walrus"}
This commit raises a `CompileError: undefined variable ...` for such cases.
This aligns the behaviour with atoms keys and maps
for state without forcing everyone to pick one or
the other.
For clarity, developers can always use required/optional.
Closes https://github.com/elixir-lang/elixir/issues/8564
This is my first attempt to contribute code to elixir, so please forgive me if this PR is completely naive.
Besides adding the `is_list/1` guards, I have updated the error message to specify that record specifications must use an atom `literal` as the name, to make it clear that the type `atom` is also not valid.