2015-10-24 35 views
18

đầu tiên tôi nhận thấy một chức năng với một dấu chấm than-mark/nổ trailing (!) Trong khi tiếp tục hướng dẫn Phoenix (trong phần Incoming Events)Chức năng Bang Elixir là gì?

def handle_in("new_msg", %{"body" => body}, socket) do 
    broadcast! socket, "new_msg", %{body: body} 
    {:noreply, socket} 
end 

nào dấu chấm than trailing nghĩa là gì? Nó có làm gì không? Tôi đã tìm kiếm xung quanh và thử tìm kiếm nhưng tôi không chắc mình đang sử dụng đúng thuật ngữ. Cho đến nay có vẻ như chức năng chỉ là quy ước sẽ gây ra lỗi nếu nó không thành công, nhưng nó luôn luôn có nghĩa là nó luôn luôn có nghĩa là.

Các chỉ đề cập đến tôi thấy nó xuất hiện trong "Lập trình Elixir" bởi Dave Thomas:

Identifiers in Elixir are combinations of upper and lower case ASCII 
characters, digits, and underscores. Function names may end with a 
question mark or an exclamation point. 

Và cũng trong the documentation nó đề cập đến:

Notice that when the file does not exist, the version with ! raises an 
error. The version without ! is preferred when you want to handle 
different outcomes using pattern matching... 

Cả những giải thích nếu điều này là một quy ước rằng các elixirists khác hoặc các nhà giả kim hay bất kỳ việc sử dụng nào. Hãy giúp tôi.

Trả lời

10

này:

Chú ý rằng khi tập tin không tồn tại, phiên bản với! gây ra lỗi . Phiên bản không có! được ưu tiên khi bạn muốn xử lý các kết quả khác nhau bằng cách sử dụng đối sánh mẫu ...

sẽ rõ ràng hơn nếu bạn xem mã nguồn. Biểu tượng ! trong tên hàm chỉ là một thỏa thuận cú pháp. Nếu bạn thấy một hàm có chứa ký hiệu ! trong tên của nó, điều đó có nghĩa là có khả năng có một hàm có cùng tên, nhưng không có biểu tượng !. Cả hai chức năng này sẽ làm điều tương tự, nhưng chúng sẽ xử lý các lỗi theo một cách khác.

Chức năng không có ! sẽ chỉ trả lại lỗi cho bạn. Bạn sẽ cần phải biết một loại lỗi và xử lý nó phụ thuộc vào loại của bạn. Nhìn vào broadcast/3 function (variant mà không !):

def broadcast(server, topic, message) when is_atom(server), 
    do: call(server, :broadcast, [:none, topic, message]) 

Nó chỉ làm cho cuộc gọi đến máy chủ nhất định và sẽ trả về kết quả của nó. Chức năng broadcast!/3 sẽ làm như vậy, nhưng: nó sẽ gọi broadcast chức năng mà không !, sẽ kiểm tra kết quả của nó và nâng cao BroadcastErrorexception:

def broadcast!(server, topic, message) do 
    case broadcast(server, topic, message) do 
     :ok -> :ok 
     {:error, reason} -> raise BroadcastError, message: reason 
    end 
    end 
+0

Cảm ơn bạn đã dành thời gian để cung cấp một ví dụ điển hình từ nguồn Phoenix. Nó trả lời câu hỏi của tôi một cách hoàn hảo. Tôi đã bị mắc kẹt giữa câu trả lời của bạn và câu trả lời tôi chọn vì cả hai đều giải thích tốt câu hỏi của tôi. Tôi đã chọn không chọn cái này chỉ bởi vì nó tập trung vào việc sử dụng của Phoenix của '!' Và, tiếc là không thể hiện trong câu hỏi của tôi, tôi quan tâm đến Elixir có nhiều điều hơn Phoenix. – Marc

+1

Tôi sẽ ăn từ của riêng tôi - và chấp nhận câu trả lời của bạn vì nó chỉ ra một chi tiết quan trọng như đã đề cập bởi @MoxleyStratton - "Quy ước bang áp dụng cho các tình huống có hai phiên bản của một hàm-- một phiên bản làm tăng ngoại lệ (phiên bản bang), và phiên bản không có. " – Marc

2

Bạn về cơ bản đã làm đúng Marc - đó là một quy ước để nói KHÔNG GÂY AN LRI nếu mọi thứ xảy ra sai.

Có tài liệu hướng dẫn, của một loại, trên page này mà nói về quyền truy cập tập tin (cuộn xuống đến cụm từ trailing nổ)

+0

Vấn đề chính của tôi là tài liệu được thực hiện trong quá trình chuyển giao và chúng tôi là cộng đồng Elixir dự kiến ​​sẽ nắm bắt được sự tinh tế. Tôi rất vui vì tôi đã có thể thu thập một cái gì đó và bạn đã cung cấp 'tài liệu cộng đồng' về việc sử dụng được chấp nhận của nó :) TY – Marc

+0

Tôi thấy câu trả lời này là sai lầm. Đọc nó, một nhà phát triển có thể kết luận rằng khi tạo một hàm gây ra lỗi, nó phải được đặt tên bằng một tiếng nổ (!). Đó không phải là ý định của quy ước bang. @ 0xAX đã nhận được điều đó ngay khi nhìn thấy hàm chữ "có nghĩa là có khả năng có một hàm có cùng tên, nhưng không có ký hiệu". Quy ước bang áp dụng cho các tình huống có hai phiên bản của một hàm-- một phiên bản làm tăng ngoại lệ (phiên bản bang) và một phiên bản không có. –

+0

@MoxleyStratton nhìn lại câu hỏi này (và chấp nhận câu trả lời) Tôi đồng ý với bạn (và không đồng ý với quyết định trước đây của tôi). – Marc

11

của nó chỉ là một quy ước đặt tên. Kiểm tra câu trả lời này - What's the meaning of "!", "?", "_", and "." syntax in elixir

! - Sẽ tăng ngoại lệ nếu hàm gặp lỗi.

Một ví dụ điển hình là Enum.fetch! (Nó cũng có cùng một Enum.fetch không ngoại lệ).Tìm phần tử tại chỉ mục đã cho (không dựa trên). Tăng OutOfBoundsError nếu vị trí đã cho nằm ngoài phạm vi của bộ sưu tập.

+0

Cảm ơn bạn đã tìm kiếm tài liệu tham khảo mà tôi đã tìm kiếm tại đây trên SO. Tôi đã hy vọng rằng những gì bạn đã liên kết sẽ có một số tham chiếu đến tài liệu chính thức nhưng tôi đoán nó sẽ phải làm. Tôi đến từ một thế giới python đầy đủ các bài báo PEP và ở đó hơn một vài đoạn được dành riêng cho "lý do", vì vậy tôi cho rằng quá trình suy nghĩ chung không có sẵn, nhưng điều này sẽ phải làm. – Marc

+0

vui lòng giúp đỡ, và elixir cũng mới và cải thiện hàng ngày, bao gồm cả tài liệu. Vì vậy, tôi nghĩ rằng các tài liệu, sẽ sớm đạt đến mức độ mong đợi của họ. – coderVishal

+1

Tôi vẫn rất biết ơn nguồn bạn đã chỉ ra, tuy nhiên, bây giờ (nhìn lại) Tôi đã chuyển câu trả lời đúng cho @ 0xAX vì sự nhấn mạnh được đặt trên các phiên bản kép của một hàm. Tôi hy vọng bạn đồng ý với quyết định này. – Marc