This was the documented behaviour on 1.9 that was broken on v1.10: (version `git` is this branch)
$ cat a.ex
defmodule A, do: nil
$ for v in 1.9.4-otp-22 1.10.2-otp-22 git; do asdf local elixir $v && echo $v; elixir -e 'IO.inspect Code.compile_file("a.ex")'; done
1.9.4-otp-22
[{A, <<70, 79, ...>>}
1.10.2-otp-22
[{A, %{attributes: [], ...}]
git
[{A, <<70, 79, ...>>}
$ for v in 1.9.4-otp-22 1.10.2-otp-22 git; do asdf local elixir $v && echo $v; elixir -e 'IO.inspect Code.require_file("a.ex")'; done
1.9.4-otp-22
[{A, <<70, 79, ...>>}]
1.10.2-otp-22
[{A, %{attributes: [], ...}]
git
[{A, <<70, 79, ...>>}]
$ for v in 1.9.4-otp-22 1.10.2-otp-22 git; do asdf local elixir $v && echo $v; elixir -e 'IO.inspect Code.load_file("a.ex")'; done
1.9.4-otp-22
[{A, <<70, 79, ...>>}]
1.10.2-otp-22
warning: Code.load_file/1 is deprecated. Use Code.require_file/2 or Code.compile_file/2 instead
nofile:1
[{A, %{attributes: [], ...}]
git
warning: Code.load_file/1 is deprecated. Use Code.require_file/2 or Code.compile_file/2 instead
nofile:1
[{A, <<70, 79, ...>>}]
This improves the error message when we accidentally use the wrong order
of arguments.
Before
iex(1)> Calendar.strftime("%h", Time.utc_now())
** (FunctionClauseError) no function clause matching in Calendar.parse/4
The following arguments were given to Calendar.parse/4:
# 1
~T[12:26:18.591978]
# 2
"%h"
# 3
%{
abbreviated_day_of_week_names: #Function<4.80759775/1 in Calendar.options/1>,
abbreviated_month_names: #Function<3.80759775/1 in Calendar.options/1>,
am_pm_names: #Function<0.80759775/1 in Calendar.options/1>,
day_of_week_names: #Function<2.80759775/1 in Calendar.options/1>,
month_names: #Function<1.80759775/1 in Calendar.options/1>,
preferred_date: "%Y-%m-%d",
preferred_date_invoked: false,
preferred_datetime: "%Y-%m-%d %H:%M:%S",
preferred_datetime_invoked: false,
preferred_time: "%H:%M:%S",
preferred_time_invoked: false
}
# 4
[]
Attempted function clauses (showing 3 out of 3):
defp parse("", _datetime, _format_options, acc)
defp parse(<<"%", rest::binary()>>, datetime, format_options, acc)
defp parse(<<char, rest::binary()>>, datetime, format_options, acc)
(elixir 1.11.0-dev) lib/calendar.ex:516: Calendar.parse/4
(elixir 1.11.0-dev) lib/calendar.ex:507: Calendar.strftime/3
After:
iex(1)> Calendar.strftime("%h", Time.utc_now())
** (FunctionClauseError) no function clause matching in Calendar.strftime/3
The following arguments were given to Calendar.strftime/3:
# 1
"%h"
# 2
~T[12:28:04.638790]
# 3
[]
Attempted function clauses (showing 1 out of 1):
def strftime(date_or_time_or_datetime, string_format, user_options) when is_map(date_or_time_or_datetime) and is_binary(string_format)
(elixir 1.11.0-dev) lib/calendar.ex:506: Calendar.strftime/3
IBM i PASE implements rename in a slightly weird way due to it
wrapping the native syscall. Expect this in the File module's
rename test when expecting an error. Fixes#9858.
This should be the behaviour documented (different from
AIX, which it's emulating, and strange for POSIX):
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apis/renameun.htm
This tracer is used to validate that all modules being invoked
in an application belongs to an application that is currently
listed as a dependency. This will help enforce umbrella application
boundaries and help users discover when they depend on Elixir and
Erlang libraries without declaring them upfront.
Thanks to @sasajuric for the proof of the concept and insights
that made this feature possible.
Closes#9847.
The documentation stated that negative numbers down to -62167219200 are
supported, but it actually works down to -377705116800. Add doctests to
illustrate the upper and lower boundaries.
Before this patch we had:
iex> import Kernel, except: :macros
** (CompileError) iex:1: invalid :except option for import, expected value to be an atom :functions, :macros, or a list literal, got: :macros
(elixir 1.11.0-dev) src/elixir_import.erl:84: :elixir_import.calculate/6
(elixir 1.11.0-dev) src/elixir_import.erl:24: :elixir_import.import/4
Pattern matching turns out to be faster than using matchspecs.
string = "~> 1.2.3 and ~> 1.0"
requirement = Version.parse_requirement!(string)
compiled_requirement = Version.compile_requirement(requirement)
new_requirement = Version.new_requirement(string)
versions =
for major <- 1..10,
minor <- 1..10,
patch <- 1..10,
pre <- [[], ["dev"]],
do: %Version{major: major, minor: minor, patch: patch, pre: pre, build: nil}
Benchee.run(
%{
"old" => fn -> Enum.map(versions, &Version.match?(&1, requirement)) end,
"old & compiled" => fn -> Enum.map(versions, &Version.match?(&1, compiled_requirement)) end,
"new" => fn -> Enum.map(versions, &Version.new_match?(&1, new_requirement)) end
},
time: 10,
memory_time: 2
)
Operating System: macOS
CPU Information: Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
Number of Available Cores: 12
Available memory: 16 GB
Elixir 1.11.0-dev
Erlang 22.0
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
parallel: 1
inputs: none specified
Estimated total run time: 42 s
Benchmarking old & compiled...
Benchmarking new...
Benchmarking old...
Name ips average deviation median 99th %
new 5.93 K 168.77 μs ±11.60% 165.99 μs 266.99 μs
old & compiled 1.18 K 849.40 μs ±7.78% 834.99 μs 1177.37 μs
old 0.0400 K 25012.15 μs ±2.98% 24798.47 μs 27617.74 μs
Comparison:
new 5.93 K
old & compiled 1.18 K - 5.03x slower +680.63 μs
old 0.0400 K - 148.20x slower +24843.38 μs
Memory usage statistics:
Name Memory usage
new 125.05 KB
old & compiled 157.52 KB - 1.26x memory usage +32.46 KB
old 250.99 KB - 2.01x memory usage +125.94 KB
**All measurements for memory usage were the same**