2016-03-19 26 views
2

ile özel bir aralık tanımlama Elixir dilini daha iyi anlamak için, ... numaralı özel bir işleç ekleyerek operatör aşırı yüklemesini yapmaya çalıştım. Bir örnek: 1...10 daha sonra 1'den yukarı ancak 10'u hariç bir aralık oluşturacaktır. (örneğin, 1...10 == 1..9)Elixir Operator Overloading: Makullar

...'un işlevselliği elbette çok benzer olduğu için, the definition of ..'u araştırdım.

Mmy modülü sonra oldu:

defmodule Sequences.Ranges do 

    defmacro first ... last do 
    case is_float(first) or is_float(last) or 
     is_atom(first) or is_atom(last) or 
     is_binary(first) or is_binary(last) or 
     is_list(first) or is_list(last) do 
     true -> 
     raise ArgumentError, 
      "ranges (first...last) expect both sides to be integers, " <> 
      "got: #{Macro.to_string({:"Sequences.Ranges...", [], [first, last]})}" 
     false -> 
     case __CALLER__.context do 
      nil -> quote do: Elixir.Range.new(unquote(first), unquote(last-1)) 
      _ -> {:%{}, [], [__struct__: Elixir.Range, first: first, last: (last-1)]} 
     end 
    end 
    end 

end 

Ancak bu modül derleme üzerine, aşağıdaki hatayı alıyorum:

== Compilation error on file lib/sequences/ranges.ex == 
** (CompileError) lib/sequences/ranges.ex:6: cannot invoke local .../1 inside match 
    (stdlib) lists.erl:1353: :lists.mapfoldl/3 

yanlış yapıyorum? Onlar ayrıştırıcı önceden tanımlanmış olan, ancak uygulanan (veya en azından varsayılan olarak ithal edilmemektedir) olan

\\, <-, |, ~>>, <<~, ~>, <~, <~>, <|>, <<<, >>>, |||, &&&, and ^^^ 

:

cevap

4

Eğer Elixir'in içinde tanımlayabilirsiniz infix operatörlerinin sadece sınırlı sayıda vardır. Bu onları özel uygulamalar için kullanılabilir hale getirir, ancak Elixir'in kendisini değiştirip yeniden derlemediğiniz sürece bu listeye eklemek için kendiniz oluşturamazsınız. Bunlardan biri değildir, bu yüzden işe yaramaz. Yorumlarınız itibaren

:

||| , &&& , ^^^ , <<< , >>> and ~~~ are not by default imported, but are part of the default Elixir standard library's Bitwise module.

fazla ayrıntı için http://www.rodneyfolz.com/custom-infix-functions-in-elixir/ bakınız.

+1

Buna ekleyelim: '|||', '&&&', '^^^', '<<<', '> >>' ve '~~~' varsayılan olarak alınmaz, ancak varsayılan Elixir standardının bir parçasıdır kütüphanenin 'Bitwise' modülü. (Onlar, sırasıyla, bitsel veya xor, sol vardiya, sağa kayma ve değil). Sonuçta sadece '\\ '(fonksiyon cümlelerinde' varsayılan 'bir argümanı belirtmek için de kullanılır),' <-' (aynı zamanda anlama-anlamada da kullanılır) ve '~>', '<~', '~>>' <<~', '<~>, '<|>' kalır. – Qqwy

+0

Bir önceki listede, geçersiz kılınmış, ancak listelerinde/desen eşleşmesini oluşturmak için listelerin içinde kullanılmış olan '|' özledim. – Qqwy

+0

Operatörlerin tam listesi ve ne için kullanıldığını görmek için https: //gist.github sayfasına bakın. com/Qqwy/3066910db6bf9adcf91b8c5e99148c85 – Qqwy