2012-02-28 10 views
9

Hơi cần thiết, tôi phát triển phần mềm với ngôn ngữ của tôi được đặt thành "C" hoặc "en_". Rất khó để sử dụng một miền địa phương khác vì tôi chỉ nói một ngôn ngữ với bất kỳ điều gì thậm chí từ xa tiếp cận lưu loát. Kết quả là, tôi thường bỏ qua những khác biệt trong hành vi có thể được giới thiệu bằng cách có các cài đặt miền địa phương khác nhau. Đáng ngạc nhiên, nhìn ra những khác biệt đôi khi sẽ dẫn đến các lỗi chỉ được phát hiện bởi một số người dùng không may sử dụng một miền địa phương khác. Trong trường hợp đặc biệt xấu, người dùng đó thậm chí không thể chia sẻ một ngôn ngữ với tôi, làm cho quá trình báo cáo lỗi trở thành một thách thức. Và, quan trọng là, rất nhiều phần mềm của tôi ở dạng thư viện; trong khi hầu như không ai trong số đó đặt ngôn ngữ, nó có thể được kết hợp với một thư viện khác, hoặc được sử dụng trong một ứng dụng mà làm đặt hành vi tạo ngôn ngữ mà tôi chưa từng trải nghiệm.Những chiến lược nào tồn tại để đảm bảo tất cả các hoạt động nhận thức cục bộ được xử lý chính xác trong tất cả các ngôn ngữ?

Để cụ thể hơn một chút, các loại lỗi mà tôi có trong đầu không thiếu văn bản bản địa hóa hoặc lỗi trong mã để sử dụng các bản địa hóa đó. Thay vào đó, tôi có nghĩa là lỗi nơi ngôn ngữ thay đổi kết quả của một số API nhận biết ngôn ngữ (ví dụ: toupper(3)) khi mã sử dụng API đó không lường trước được khả năng thay đổi đó (ví dụ: ở địa phương Thổ Nhĩ Kỳ, toupper không thay đổi "i" tới "I" - có khả năng là một vấn đề đối với một máy chủ mạng cố gắng nói một giao thức mạng cụ thể tới một máy chủ khác).

Một vài ví dụ về lỗi như vậy trong phần mềm tôi duy trì:

Trong quá khứ, một cách tiếp cận tôi đã thực hiện để đối phó với điều này là viết các bài kiểm tra hồi quy mà thay đổi rõ ràng miền địa phương thành một nơi mà mã được biết là không hoạt động, thực hiện mã, xác minh hành vi đúng và n khôi phục ngôn ngữ gốc. Điều này hoạt động tốt, nhưng chỉ sau khi ai đó đã báo cáo một lỗi, và nó chỉ bao gồm một khu vực nhỏ của một codebase.

Một cách tiếp cận khác có vẻ như là có một hệ thống tích hợp liên tục (CIS) được thiết lập để chạy một bộ kiểm tra đầy đủ trong môi trường với một bộ miền địa phương khác. Điều này cải thiện tình hình một chút, bằng cách đưa ra nhiều bảo hiểm trong một miền địa phương thay thế như bộ thử nghiệm thường đưa ra. Một thiếu sót nữa là có rất nhiều, nhiều, nhiều miền địa phương và mỗi miền có thể gây ra các vấn đề khác nhau. Trong thực tế, có thể chỉ có một tá cách khác nhau mà một miền địa phương có thể phá vỡ một chương trình, nhưng có hàng chục cấu hình thử nghiệm bổ sung đang đánh thuế tài nguyên (đặc biệt là một dự án đã kéo dài giới hạn tài nguyên của nó bằng cách thử nghiệm trên các nền tảng khác nhau phiên bản, v.v.) Một cách tiếp cận khác xảy ra với tôi là sử dụng (có thể là lần đầu tiên tạo) một ngôn ngữ mới hoàn toàn khác với miền địa phương "C" theo mọi cách - có bản đồ trường hợp khác nhau, sử dụng dấu tách hàng nghìn khác, định dạng ngày khác nhau, vv Vị trí này có thể được sử dụng với một cấu hình CIS bổ sung và hy vọng dựa vào để nắm bắt bất kỳ lỗi nào trong mã có thể được kích hoạt bởi bất kỳ ngôn ngữ nào.

Địa điểm thử nghiệm đã tồn tại chưa? Có sai sót với ý tưởng này để thử nghiệm cho khả năng tương thích miền địa phương?

Các phương pháp khác để thử nghiệm miền địa phương có người được thực hiện là gì?

Tôi chủ yếu quan tâm đến ngôn ngữ POSIX, vì đó là những điều tôi biết. Tuy nhiên, tôi biết rằng Windows cũng có một số tính năng tương tự, do đó, thêm thông tin (có lẽ với thông tin cơ bản về cách các tính năng này hoạt động), có lẽ cũng hữu ích.

+2

Câu hỏi hay! Tôi không nghĩ có một câu trả lời hay; cụ thể, Python rõ ràng [không hỗ trợ] (http://docs.python.org/library/locale.html#background-details-hints-tips-and-caveats) các thao tác chuỗi bất biến locale. Tôi nghi ngờ giải pháp là tạo danh sách tất cả các API sử dụng các thiết lập nhận biết miền địa phương và, tốt, không sử dụng chúng. – katrielalex

+0

Tôi rất vui vì tôi nói tiếng Đức (tiếng mẹ đẻ) và một phần tiếng Nhật ngoài tiếng Anh cho những thứ này.Tuy nhiên, một câu hỏi thực sự hay, bởi vì thậm chí biết nhiều hơn một ngôn ngữ không thực hiện nhiệm vụ thực sự dễ dàng hơn nhiều (ok, có thể đọc lỗi, đó là một phần thưởng tốt đẹp, nhưng việc tìm ra dòng có vấn đề hoạt động ngay cả khi bạn không biết những gì tin nhắn nói) – Voo

Trả lời

3

Tôi chỉ kiểm tra mã của bạn để sử dụng sai các chức năng như toupper. Theo mô hình miền địa phương C, các chức năng như vậy chỉ nên được coi là hoạt động trên văn bản ngôn ngữ tự nhiên bằng ngôn ngữ của ngôn ngữ. Đối với bất kỳ ứng dụng nào liên quan đến văn bản đa ngôn ngữ tiềm năng, điều này có nghĩa là các chức năng như tolowerkhông được sử dụng ở tất cả.

Nếu mục tiêu của bạn là POSIX, bạn có thể linh hoạt hơn một chút do chức năng uselocale giúp tạm thời ghi đè ngôn ngữ trong một chuỗi đơn lẻ (tức là không làm rối loạn trạng thái toàn cầu của chương trình của bạn). Sau đó, bạn có thể giữ miền địa phương C trên toàn cầu và sử dụng tolower vv cho văn bản ASCII/máy định hướng (như tệp cấu hình và như vậy) và chỉ uselocale đến ngôn ngữ đã chọn của người dùng khi làm việc với văn bản ngôn ngữ tự nhiên từ ngôn ngữ được cho biết.

Nếu không (và có lẽ ngay cả khi bạn cần nâng cao hơn), tôi nghĩ giải pháp tốt nhất là hoàn toàn loại bỏ các chức năng như tolower và viết các phiên bản ASCII của riêng bạn cho văn bản cấu hình và tương tự. thư viện nhận thức cho văn bản tự nhiên.

Một vấn đề dính mà tôi chưa chạm vào là dấu tách thập phân liên quan đến các chức năng như snprintfstrtod. Thay đổi nó thành một số , thay vì . ở một số miền địa phương có thể làm hỏng khả năng phân tích tệp của bạn bằng thư viện C. Giải pháp ưa thích của tôi chỉ đơn giản là không bao giờ đặt ngôn ngữ LC_NUMERIC. (Và tôi là một nhà toán học vì vậy tôi có xu hướng tin rằng con số phải là phổ quát, không phải theo quy ước văn hóa.) Tùy thuộc vào đơn đăng ký của bạn, danh mục địa phương duy nhất thực sự cần thiết chỉ có thể là LC_CTYPE, LC_COLLATELC_MESSAGES. Cũng thường hữu ích là LC_MONETARYLC_TIME.

+0

'tolower/upper' cũng có vấn đề bổ sung mà chúng thường được sử dụng để so sánh những thứ không phân biệt chữ hoa chữ thường, mà không hoạt động với unicode. Rất nhiều lý do để ở xa xa unicdoe càng tốt (có nghĩa là: sử dụng một thư viện cấp cao, không phải "chỉ cần giả định ascii") - rất nhiều lỗi tinh tế chờ đợi ở đó, ugh. – Voo

+0

Cảm ơn. "Kiểm toán và loại bỏ" chắc chắn là một chiến lược; Tôi đặc biệt quan tâm đến các kỹ thuật để xác minh, đặc biệt là theo cách tự động, rằng chiến lược đã thành công và bảo vệ chống lại các hồi quy trong tương lai. –

+0

Công cụ yêu thích của tôi cho điều này sẽ là một búa tạ, nghĩa là chỉ cần loại bỏ tất cả việc sử dụng các hàm lớp/ký tự có thể có vấn đề và tất cả các cách sử dụng 'setlocale' với' LC_NUMERIC'. Điều đó làm cho nó khá dễ dàng để xác minh tính chính xác. –

2

Bạn có hai vấn đề khác nhau cần giải quyết để trả lời câu hỏi của mình: kiểm tra mã của bạn và giải quyết các vấn đề với mã người khác.

Kiểm tra mã của riêng bạn - Tôi đã xử lý điều này bằng cách sử dụng 2 hoặc 3 ngôn ngữ dựa trên tiếng Anh trong môi trường CI: en_GB (collation), en_ZW (hầu như mọi thứ thay đổi nhưng bạn vẫn có thể đọc lỗi) và sau đó en_AU (ngày, đối chiếu)

Nếu bạn muốn chắc chắn rằng mã của bạn hoạt động với tên tập tin multibyte sau đó bạn cũng cần phải thử nghiệm với ja_jp

Xử lý với mã của những người khác là bằng nhiều cách giải pháp của tôi khó khăn nhất và cho đó là để lưu trữ các giá trị ngày tháng (hầu như luôn là ngày :) trong giá trị ngày/giờ thô của chúng và luôn giữ giữ chúng dưới dạng GMT. Sau đó, khi bạn đang vượt qua ranh giới của ứng dụng của bạn, bạn chuyển đổi sang định dạng thích hợp.

PyTZ và PyICU rất hữu ích khi thực hiện ở trên.