defmodule Methods do @moduledoc """ Documentation for `Methods`. This adds method calls for Elixir structs. Call methods with "..". This breaks ranges if the second argument is a function call. defmodule Rect do defstruct [width: 0, height: 0] def area(self) do self.width * self.height end end defmodule Main do use Methods def main do r1 = %Rect{width: 10, height: 10} area = r1..area() end end """ import Kernel, except: [..: 2] defmacro __using__(_opts) do quote do import Kernel, except: [..: 2] import Methods end end @doc """ Method call. myDog..bark() If myDog is a %Dog{}, this calls Dog.bark(myDog). If the thing after the ".." doesn't look like a method call, this falls back to constructing a range. """ defmacro aa..bb do case bb do {method, _, args} -> args = [aa | args] quote do apply(unquote(aa).__struct__, unquote(method), unquote(args)) end _ -> quote do Range.new(unquote(aa), unquote(bb), 1) end end end end