Current section
5 Versions
Jump to
Current section
5 Versions
Compare versions
4
files changed
+17
additions
-35
deletions
| @@ -7,12 +7,15 @@ Turns a module's specs into callbacks. | |
| 7 7 | |
| 8 8 | Lets you state that a module behaves like another, without writing behaviour callbacks. |
| 9 9 | |
| 10 | + Uses a macro for 1.7, until https://github.com/elixir-lang/elixir/issues/8085 is fixed. |
| 11 | + |
| 10 12 | For example: |
| 11 13 | ```elixir |
| 12 14 | defmodule API do |
| 13 15 | use BehavesLike |
| 16 | + import BehavesLike, only: [spec_and_callback: 1] |
| 14 17 | |
| 15 | - @spec get(binary()) :: {:ok, any()} | {:error, any()} |
| 18 | + spec_and_callback get(binary()) :: {:ok, any()} | {:error, any()} |
| 16 19 | def get(id) do |
| 17 20 | Backend.get(id) |
| 18 21 | end |
| @@ -28,8 +31,6 @@ defmodule Backend do | |
| 28 31 | end |
| 29 32 | ``` |
| 30 33 | |
| 31 | - Please note, this library uses undocumented private calls to manipulate the elixir compiler's ets tables. Use at your own risk. |
| 32 | - |
| 33 34 | ## Installation |
| 34 35 | |
| 35 36 | From Hex: |
| @@ -37,11 +38,11 @@ From Hex: | |
| 37 38 | ```elixir |
| 38 39 | def deps do |
| 39 40 | [ |
| 40 | - {:behaves_like, "~> 0.3.0"} |
| 41 | + {:behaves_like, "~> 0.4.0"} |
| 41 42 | ] |
| 42 43 | end |
| 43 44 | ``` |
| 44 45 | |
| 45 46 | ## Usage |
| 46 47 | |
| 47 | - Just add `use BehavesLike` to your module, then you can use the standard `@behaviour` attribute in other modules to refer to it. |
| 48 | + Import the required macro, then declare your specs with `spec_and_callback/1`, as in the example above. |
| @@ -1,14 +1,13 @@ | |
| 1 1 | {<<"app">>,<<"behaves_like">>}. |
| 2 2 | {<<"build_tools">>,[<<"mix">>]}. |
| 3 3 | {<<"description">>, |
| 4 | - <<"Automatically creates a behaviour from a module's specs. This lib uses undocumented calls, please don't use it. :)">>}. |
| 5 | - {<<"elixir">>,<<"~> 1.7.1">>}. |
| 4 | + <<"Automatically creates a behaviour from a module's specs.">>}. |
| 5 | + {<<"elixir">>,<<"~> 1.6">>}. |
| 6 6 | {<<"files">>, |
| 7 7 | [<<"lib">>,<<"lib/behaves_like.ex">>,<<".formatter.exs">>,<<"mix.exs">>, |
| 8 8 | <<"README.md">>,<<"LICENSE">>]}. |
| 9 9 | {<<"licenses">>,[<<"MIT">>]}. |
| 10 10 | {<<"links">>,[{<<"GitHub">>,<<"https://github.com/koudelka/behaves_like">>}]}. |
| 11 | - {<<"maintainers">>,[<<"Michael Shapiro">>]}. |
| 12 11 | {<<"name">>,<<"behaves_like">>}. |
| 13 12 | {<<"requirements">>,[]}. |
| 14 | - {<<"version">>,<<"0.3.0">>}. |
| 13 | + {<<"version">>,<<"0.4.0">>}. |
| @@ -7,9 +7,9 @@ defmodule BehavesLike do | |
| 7 7 | For example: |
| 8 8 | ```elixir |
| 9 9 | defmodule API do |
| 10 | - use BehavesLike |
| 10 | + import BehavesLike, only: [spec_and_callback: 1] |
| 11 11 | |
| 12 | - @spec get(binary()) :: {:ok, any()} | {:error, any()} |
| 12 | + spec_and_callback get(binary()) :: {:ok, any()} | {:error, any()} |
| 13 13 | def get(id) do |
| 14 14 | Backend.get(id) |
| 15 15 | end |
| @@ -26,28 +26,10 @@ defmodule BehavesLike do | |
| 26 26 | ``` |
| 27 27 | """ |
| 28 28 | |
| 29 | - defmacro __using__(_opts) do |
| 29 | + defmacro spec_and_callback(spec) do |
| 30 30 | quote do |
| 31 | - @before_compile unquote(__MODULE__) |
| 31 | + @spec unquote(spec) |
| 32 | + @callback unquote(spec) |
| 32 33 | end |
| 33 34 | end |
| 34 | - |
| 35 | - defmacro __before_compile__(_env) do |
| 36 | - quote do |
| 37 | - {_set, bag} = :elixir_module.data_tables(__MODULE__) |
| 38 | - unquote(__MODULE__).get_typespecs(bag, :spec) |
| 39 | - |> Enum.each(&unquote(__MODULE__).store_typespec(bag, :callback, &1)) |
| 40 | - end |
| 41 | - end |
| 42 | - |
| 43 | - @doc false |
| 44 | - def get_typespecs(bag, type) do |
| 45 | - :ets.lookup_element(bag, type, 2) |
| 46 | - end |
| 47 | - |
| 48 | - @doc false |
| 49 | - def store_typespec(bag, key, value) do |
| 50 | - :ets.insert(bag, {key, value}) |
| 51 | - :ok |
| 52 | - end |
| 53 35 | end |
| @@ -1,17 +1,17 @@ | |
| 1 1 | defmodule BehavesLike.MixProject do |
| 2 2 | use Mix.Project |
| 3 3 | |
| 4 | - @version "0.3.0" |
| 4 | + @version "0.4.0" |
| 5 5 | |
| 6 6 | def project do |
| 7 7 | [ |
| 8 8 | app: :behaves_like, |
| 9 9 | version: @version, |
| 10 | - elixir: "~> 1.7.1", |
| 10 | + elixir: "~> 1.6", |
| 11 11 | start_permanent: Mix.env() == :prod, |
| 12 12 | deps: deps(), |
| 13 13 | dialyzer: dialyzer(), |
| 14 | - description: "Automatically creates a behaviour from a module's specs. This lib uses undocumented calls, please don't use it. :)", |
| 14 | + description: "Automatically creates a behaviour from a module's specs.", |
| 15 15 | package: package(), |
| 16 16 | docs: docs(), |
| 17 17 | ] |