From 152c784a075bcad4e8a74ac3a8a17dd71f0bb472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 24 Jul 2012 13:04:33 +0200 Subject: [PATCH] Add binary_part to the list of guard functions --- lib/elixir/lib/kernel.ex | 21 +++++++++++++++++++++ lib/elixir/src/elixir_def.erl | 4 ++-- lib/elixir/src/elixir_dispatch.erl | 4 +--- lib/elixir/test/elixir/code_test.exs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 76224bb1df..4972a65466 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -352,6 +352,27 @@ defmodule Kernel do @spec atom_to_list(atom), do: list defmacro atom_to_list(atom) + @doc """ + Extracts the part of the binary starting at `start` with length `length`. + Binaries are zero-indexed. + + If start or length references in any way outside the binary, an + `ArgumentError` exception is raised. + + Allowed in guard tests. + + ## Examples + + binary_part "foo", 1, 2 #=> "oo" + + A negative length can be used to extract bytes at the end of a binary: + + binary_part "foo", 3, -1 #=> 1 + + """ + @spec binary_part(binary, pos_integer, integer), do: binary + defmacro binary_part(binary, start, length) + @doc """ Returns the atom whose text representation is `binary`. If `encoding` is latin1, no translation of bytes in the binary is done. If `encoding` is utf8 or unicode, diff --git a/lib/elixir/src/elixir_def.erl b/lib/elixir/src/elixir_def.erl index 41e1f3ebbd..68b423412f 100644 --- a/lib/elixir/src/elixir_def.erl +++ b/lib/elixir/src/elixir_def.erl @@ -257,7 +257,7 @@ store_each(Check, Kind, File, Location, Stack, Table, Defaults, {function, Line, FinalDefaults = Defaults + StoredDefaults, FinalClauses = Clauses ++ StoredClauses, check_valid_kind(Line, File, Name, Arity, Kind, StoredKind), - check_valid_defaults(Line, File, Name, Arity, Defaults), + check_valid_defaults(Line, File, Name, Arity, FinalDefaults), Check andalso (Stack == StoredStack) andalso check_valid_clause(Line, File, Name, Arity, Table); [] -> FinalLocation = Location, @@ -297,7 +297,7 @@ add_to_guards(Line, Expr, Clauses) -> %% Format errors format_error({clauses_with_docs,{Name,Arity}}) -> - io_lib:format("function ~s/~B has default values and multiple clauses, it is recommended to use a separate clause for declaring defaults", [Name, Arity]); + io_lib:format("function ~s/~B has default values and multiple clauses, use a separate clause for declaring defaults", [Name, Arity]); format_error({private_doc,{Name,Arity}}) -> io_lib:format("function ~s/~B is private, @doc's are always discarded for private functions", [Name, Arity]); diff --git a/lib/elixir/src/elixir_dispatch.erl b/lib/elixir/src/elixir_dispatch.erl index 91023a8211..d227ab6caa 100644 --- a/lib/elixir/src/elixir_dispatch.erl +++ b/lib/elixir/src/elixir_dispatch.erl @@ -254,9 +254,7 @@ in_erlang_functions() -> { abs, 1 }, { atom_to_binary, 2 }, { atom_to_list, 1 }, - % Those are allowed in guard clauses, so we need to bring them back. - % { binary_part, 2 }, - % { binary_part, 3 }, + { binary_part, 3 }, { binary_to_atom, 2 }, { binary_to_existing_atom, 2 }, { binary_to_list, 1 }, diff --git a/lib/elixir/test/elixir/code_test.exs b/lib/elixir/test/elixir/code_test.exs index d9e3c11ab6..3706dfaf69 100644 --- a/lib/elixir/test/elixir/code_test.exs +++ b/lib/elixir/test/elixir/code_test.exs @@ -70,6 +70,6 @@ defmodule CodeTest do test :compile_info_returned_with_source_accessible_through_keyword_module do compile = __MODULE__.__info__(:compile) - refute_nil Keyword.get(compile, :source) + assert Keyword.get(compile, :source) != nil end end