2015-05-29 10 views
7

Nếu dự án của tôi đang sử dụng bản đồ "người" với hình dạng {:firstName :lastName :address} và tôi muốn thay đổi hình dạng đó thành {:name {:firstName :lastName} :address}, tôi có thể làm gì để đảm bảo rằng tôi đã thực hiện các thay đổi tương ứng ở mọi nơi đối tượng được sử dụng?Cấu trúc chính xác trong khi tái cấu trúc tại Clojure

Trong Java, đơn giản như mọi nơi tôi vẫn có person.firstName sẽ phát hành lỗi biên dịch. Trong Clojure tôi có thể thậm chí không gặp lỗi thời gian chạy , nhưng chỉ lưu dữ liệu xấu vào máy chủ. Tôi cho rằng không thể bảo đảm đảm bảo tính chính xác, nhưng có gì khác ngoài lược răng?

+1

Nếu bạn muốn có lỗi thời gian biên dịch, bạn cũng có thể xem xét sử dụng 'core.typed'. –

+0

Các câu trả lời đã được đưa ra là tốt, nhưng tôi sẽ lưu ý rằng đây có thể là một tình huống quen thuộc với tìm kiếm biểu thức chính quy và thay thế trong trình soạn thảo của lập trình viên tốt. Nếu các biểu thức thông thường không đủ linh hoạt và bạn có một cơ sở mã lớn, nó thậm chí có thể đáng giá mã hóa một đoạn mã thao tác văn bản bằng ngôn ngữ yêu thích của bạn cho thao tác chuỗi. Hoặc bạn thậm chí có thể sử dụng Clojure. Đó là, sau khi tất cả, rất tốt lúc đọc nguồn Clojure, và các macro Clojure là tốt lúc viết lại nguồn Clojure. Tất cả điều này phụ thuộc vào bao nhiêu mã bạn phải refactor. – Mars

Trả lời

6

Clojure có các thư viện cung cấp định nghĩa và xác thực dữ liệu. Ví dụ: bạn có thể sử dụng https://github.com/Prismatic/schema

Về độ khó của thời gian biên dịch so với lỗi thời gian chạy ... tốt, vấn đề đó không phải là duy nhất đối với Clojure. Để trích dẫn John Carmack: "Thách thức của lisp là làm cho chương trình của bạn chạy, thách thức của Haskell là làm cho nó biên dịch."

4

Tôi đồng ý với @noahlz - nếu bạn muốn thực sự chắc chắn sau đó, bạn sẽ phải sử dụng thư viện như thư viện mà anh ta đề xuất. Việc tái cấu trúc lớn với bản đồ có thể là một vấn đề, đó là sự thật.

Có nói rằng, bạn hơi có thể cải thiện cơ hội của bạn trong trường hợp của bạn nếu bạn sử dụng bản ghi có chức năng xây dựng của nó để tạo ra của bạn person (và vẫn giữ lại những điều tốt đẹp về bản đồ):

(defrecord Person [name address]) 

;; Okay. No problem 
(def scott (->Person {:firstname "Scott" :lastname "Lowe"} 
        "23 Hope Street, Edinburgh")) 
;; But then... 
(def scott (->Person "Scott" 
        "Lowe" 
        "23 Hope Street, Edinburgh")) 
;; Boom! 
ArityException Wrong number of args (3) passed to: user/eval990/->Person--1005 

Bây giờ này ví dụ bắt vấn đề trong thời gian chạy, và nó rõ ràng sẽ chỉ giúp đỡ trong một số trường hợp đơn giản. Nhưng các công cụ phân tích tĩnh cũng sẽ nhận lỗi này vào thời điểm phát triển (ví dụ: các plugin Clojure như Cursive có sẵn cho IntelliJ).

Các vấn đề liên quan