در عمل کامپیوترها نمیتوانند کاراکترها و علائم را ذخیره کنند، آنها فقط اعداد را ذخیره میکنند. روشهای بیشماری برای نمایش دادن کاراکترهای زبان انسانی( مانند حرف A، علامت به اضافه، وغیره ) به عنوان عدد، وجود دارد، و این امر که روشهای متفاوت بسیار زیادی، واقعاً به کار برده شد، به بینظمی منجر گردیده است.
کامپیوترهای اولیه (حداقل در ایالات متحده) در دو استاندارد برای طرحریزی(نگاشت) کاراکترهای US English به اعداد و بالعکس، به یکدیگر نزدیک شدند: ASCII و EBCDIC. دومی به تدریج تا اواخر قرن بیستم منسوخ گردید و ASCII ( کد استاندارد امریکایی برای تبادل اطلاعات) را به عنوان استاندارد اصلی باقی گذاشت.
مشکل با ASCII آن است که برای زبانهای غیر از انگلیسی، یا حتی برای برخی کلمات انگیسیِ وابسته به مزیتهای انشایی نویسنده، یا شاید نوشته شده با آوا نماها (به عنوان مثال rôle و naïve) خیلی محدود است. ASCII تنها بیست و شش حرف از الفبای انگلیسی (بزرگ و کوچک)، ارقام 0 تا 9، و مقداری نشانهگذاری اصلی را پوشش میدهد -- به طور معمول آنهایی که شما در صفحه کلید US کامپیوتر میبینید. در ماشینهای یونیکسی برای دیدن فهرست آنها میتوانید man ascii را تایپ کنید.
اکثر کامپیوترها از یک بایت هشت بیتی به عنوان واحد ذخیرهشان (یعنی یک دامنه از 0 تا 255 هنگامی که مانند اعداد صحیح غیر منفی بیان میشوند) استفاده میکنند. ASCII فقط کاراکترهای هفت بیتی (0 تا 127) تعریف میکند، یک میرات روزهایی که ارتباطات راه دور دادهها به طور قابل ملاحظهای آهسته و بیشتر مستعد خطا بود. چون ASCII تنها نصف محدوده یک بایت را استفاده میکند، این مطلب فضایی را برای افراد باقی گذاشت که مجموعههای کاراکتری خودشان را داخل یک بایت منفرد تعریف کنند.
(بسیاری از کاربران DOS/Windows مایکروسافت باور دارند که ASCII تمام دامنه 0 تا 255 را با صورتکهای خندان و کاراکترهای ترسیم خطوط و مانند آن پوشش میدهد. این تصور نادرست است. مجموعه کاراکتر معروف DOS در حقیقت IBM code page 437 است، که یکی از چندین فوقمجموعه ASCII میباشد. ASCII خودش منحصر به 127 کاراکتر است.)
کاربران کامپیوتر در کشورهای خارج از US با استفاده از ASCII قادر به نمایش زبانهای نوشتاری خود نبودند، بنابراین در حالیکه برنامهنویسان US از فضای 128 تا 255 برای ایجاد کاراکترهای ترسیمی و نمادهای ریاضی استفاده میکردند، اروپاییها آنها را برای افزودن حروف اضافیشان و حروف دارای تکیه صدا به کار میبردند. این مطلب بواسطه مجموعه دیگری از استانداردهای رشد یافته یعنی ISO 8859 به بینظمی بیشتر (نه به طور تعجبآور) منجر گردید. توجه نمایید که اینها فوقمجموعههای ASCII میباشند. استاندارد ISO-8859-1 که به عنوان Latin-1 نیز شناخته میشود، استاندارد مسلط برای ایستگاههای کاری یونیکس در امریکای شمالی و غرب اروپا شد.
به هر حال، این نیز برخی موضوعات را حل نشده باقی گذاشت. نخست آنکه بازهم رقابت استانداردها وجود داشت، اروپای شرقی دارای الفبای بسیار متفاوت با اروپای غربی است، و استانداردهای متنوع ISO 8859 نیز با هم ناسازگار هستند. دوم، کشورهای آسیایی در مقایسه با کشورهای امریکایی-اروپایی دارای روشهای به طور ریشهای متفاوتی در نوشتن میباشند، و حتی مجموعه کاراکترهای آنها با فضای یک بایت منفرد (که تنها 256 علامت مختلف را مجاز میکند) مطابقت ندارد.
استاندارد Unicode تلاش دارد این مطلب را هدفگیری نماید: به جای تعریف فقط 256 علامت، هزارها نشانه تعریف میکند. اگر یک کامپیوتر باید هر علامت سندی را که از مجموعه کدهای یونیکد استفاده نموده، نمایش بدهد، به سه بایت برای هر علامت نیاز دارد، این مطلب فضای مورد نیاز برای اسناد انگلیسی ساده را نسبت به آنچه قبلاً استفاده میشد، سه برابر میسازد، که قسمت اعظم آن فضا با صفرها اشغال میشود.
بنابراین، به منظور تلاش برای حفظ برخی اثربخشیها (و همچنین بعضی سازگاریها با فایلهای دادهای موجود)، کدگذاریهای متنوعی از کاراکترهای یونیکد ایجاد گردید، در حال حاضر محبوبترینِ اینها (حداقل در میان انگلیسی زبانان) UTF-8 میباشد، که یک کدگذاری با پهنای متغییر است. یک سند اسکی(ASCII) ساده، همچنین یک سند UTF-8 معتبر نیز هست، کاراکترهای یک بایتی اسکی در UTF-8 با استفاده از همان یک بایت نمایش داده میشوند. به هرحال، UTF-8 رشتههای چندبایتی قادر به نمایش تمام کاراکترهای یونیکد را ارائه میکند (در برخی حالتها تا استفاده از چهار بایت برای هر کاراکتر).
از سال 2009، UTF-8 استاندارد نمایان برای توزیعهای لینوکس است، هرچند که بازهم مشکلات زیادی با پیادهسازیها وجود دارد.
بنابراین، «منطقه»(locale) چیست؟ چون اینهمه استانداردهای غیر معمول، و انواع مختلف کامپیوتر اینقدر زیاد وجود دارد، که برخی از آنها فقط از بعضی استانداردها پشتیبانی میکنند، اهمیت دارد که قادر باشیم بگوییم که شما در حال کار با کدام استاندارد هستید. این جایی است که مناطق از آن ناشی میشوند.
یک منطقه، مجموعه قواعدی است که تعیین میکنند اطلاعات با در نظر گرفتن انسان چگونه پردازش و نمایش داده میشود. کدگذاری کاراکترها (که در بخش اول این صفحه در باره آن صحبت کردیم) و ترتیبی که آن کاراکترها در آن مرتب میشوند، قالب نمایش تاریخ و زمان، قواعد نمایش اعداد بزرگ و اعداد با قسمت اعشاری، و غیره را پوشش میدهد.
مثالها: یک امریکایی ممکن است «روز سوم ژانویه سال 2009 میلادی» را به صورت 1/3/09 بنویسد، در حالیکه یک شخص انگلیسی ممکن است همان تاریخ را به صورت 3/1/09 بنویسد. یک برنامهنویس کامپیوتر احتمالاً 2009-01-03 را به کار خواهد برد. در ضمن دوست امریکایی ما عدد «ده هزار و یکصدم» را به شکل 10,000.01 مینویسد، بسیار آزار دهنده برای همکار آلمانیاش که به جای آن به صورت 10000,01 مینویسد.
یک سیستم یونیکس دارای فرمانی به نام locale میباشد که برای نشان دادن منطقهای که یک کاربر(یا به طور دقیقتر، یک فرایند) در لحظه مشغول استفاده از آن است، و لیست کردن تمام مناطق به کار میرود. برای مثال
imadev:~$ locale LANG=en_US.iso88591 LC_CTYPE="en_US.iso88591" LC_COLLATE="en_US.iso88591" LC_MONETARY="en_US.iso88591" LC_NUMERIC="en_US.iso88591" LC_TIME=POSIX LC_MESSAGES="en_US.iso88591" LC_ALL=
این دستور منطقهای را که در حال حاضر مورد استفاده است نشان میدهد. برای دیدن آنهایی که به جای آن میتوانند انتخاب بشوند:
imadev:~$ locale -a C POSIX C.iso88591 C.utf8 univ.utf8 ar_DZ.arabic8 ar_SA.arabic8 ar_SA.iso88596 bg_BG.iso88595 cs_CZ.iso88592 da_DK.iso88591 da_DK.roman8 nl_NL.iso88591 nl_NL.roman8 en_GB.iso88591 en_GB.roman8 en_US.iso88591 en_US.roman8 fi_FI.iso88591 fi_FI.roman8 fr_CA.iso88591 fr_CA.roman8 fr_FR.iso88591 fr_FR.roman8 de_DE.iso88591 de_DE.roman8 el_GR.greek8 el_GR.iso88597 iw_IL.hebrew8 iw_IL.iso88598 hu_HU.iso88592 is_IS.iso88591 is_IS.roman8 it_IT.iso88591 it_IT.roman8 no_NO.iso88591 no_NO.roman8 pl_PL.iso88592 pt_PT.iso88591 pt_PT.roman8 ro_RO.iso88592 ru_RU.iso88595 hr_HR.iso88592 sk_SK.iso88592 sl_SI.iso88592 es_ES.iso88591 es_ES.roman8 sv_SE.iso88591 sv_SE.roman8 th_TH.tis620 tr_TR.iso88599 tr_TR.turkish8 C.iso885915 da_DK.iso885915@euro de_DE.iso885915@euro en_GB.iso885915@euro es_ES.iso885915@euro fi_FI.iso885915@euro fr_CA.iso885915 fr_FR.iso885915@euro is_IS.iso885915@euro it_IT.iso885915@euro nl_NL.iso885915@euro no_NO.iso885915@euro pt_PT.iso885915@euro sv_SE.iso885915@euro zh_CN.hp15CN zh_TW.eucTW
در این مرحله، خواننده باید درک کند که چرا بخش نخست این صفحه به مجموعه کدگذاریهای کاراکتر اختصاص یافته بود. بدون فهم آنکه "iso885915" به چه معنا میباشد، این لیست تا اندازهای مرموز میبود.
یک نام منطقه دارای سه جزء سازنده است. بخش اول که دو حرف کوچک میباشد، زبانی را که استفاده میشود، نشان میدهد. برای مثال en به معنی انگلیسی و es اسپانیولی، de آلمانی است و به همین منوال، با استفاده از دو حرف کدهای کشوری که گویش اصلی هر زبان از آن ناشی گردیده است.
بخش دوم (پس از خط زیر) کشور واقعی که کاربر در آن است(یاآنکه کاربر میخواهد قواعد منطقه آن را به اجرا درآورد)، و اساساً برای گویشهای متفاوت یک زبان به کار میرود. en_US و en_GB دارای چند تفاوت در املای واژهها، علائم پول رایج مختلف، و مانند آن میباشند.
جزء سازنده سوم(بعد از نقطه) کدگذاری کاراکتر است. توجه نمایید که املای نام کدگذاری در میان سیستمها کاملاً استاندارد شده نمیباشد. iso885915 املای معمولی برای یک کدگذاری ISO-8859-15 میباشد، اماسیستمهای دیگر ممکن است(برای مثال) به ISO8859-15 نیاز داشته باشند. شما باید از دستور locale -a برای دیدن آنچه در سیستم شما معتبر است و چطور نوشته میشود، استفاده نمایید.
نامهای خاص C و POSIX برای این مطلب یک استثنا هستند. آنها در هرجایی لازم میشوند و مترادف هستند، آنها(به طور اساسی) به معنی «اسکی، انگلیسی US بدون اِعمال هیچ قاعده خاص» میباشند. خروجی تحت این منطقه به طور عادی با استانداردهای ISO و RFC برای تاریخ، زمان و غیره مطابقت دارد، جداکننده هزارها را کاملاً حذف میکند، از کدگذاری ASCII واقعی کمیتها برای مرتبسازی کاراکترها و مانند آن، استفاده میکند(به طور کلی با پیش فرض قرار دادن «قواعد محاسبه قراردادی US»).
شما منطقهای را که میخواهید استفاده کنید به وسیله تنظیم متغیرهای محیط تعیین میکنید. (برای بحث در باره اینکه چگونه و کجا متغیرهای محیط جهت نشستهای محاورهای خود را تنظیم کنید، صفحه DotFiles را ببینید.) متغیرهای متنوع LC_* اگر تنظیم شوند، قواعد ویژهای جهت پیروی تعریف میکنند، متغیر LANG ذخیرهای برای هر کدام از متغیرهای LC_* که تنظیم نشوند تعریف میکند. در اکثر حالتهای رایج، شما تنها LANG را تنظیم خواهید نمود.
برای به دست آوردن تنظیماتی که در مثال سیستم خود دیدیم، میتوانستیم از موردی مانند این استفاده کنیم:
imadev:~$ cat .profile ... LANG=en_US.iso88591; LC_TIME=POSIX export LANG LC_TIME ...
(توجه: فایل .profile تنها برای برخی از انواع لاگینها درست است. در صورتیکه نمیدانید به ویرایش یا ایجاد کدام فایل نیاز دارید صفحه DotFiles را ببینید.)
این مثال قواعد «US English، با کدگذاری ISO-8859-1» را برای اکثر موارد، اما قواعد POSIX را به منظور نمایش تاریخ و زمان به ما ارائه میکند.
چون اینها متغیرهای محیط هستند، میتوانیم بررسی کنیم که وقتی مواردی را تغییر میدهیم چه اتفاقی رخ میدهد.
imadev:~$ LC_TIME=POSIX date Thu Apr 16 10:32:03 EDT 2009 imadev:~$ LC_TIME=en_US.iso88591 date Thu, Apr 16, 2009 10:32:13 AM
برای دانستن جزئیات آنچه سیستم شما با مناطق انجام میدهد، لازم است مستندات سیستم خودتان (چنین مواردی بسیار زیاد در معرض برداشت پیادهسازی کنندگان میباشد) را بررسی کنید. سیستمهای دبیان دارای locale(7) (برای خواندن آن man 7 locale را تایپ کنید)، و HP-UX دارای lang(5) میباشند و به همین ترتیب.
وقتی تعیین کردهاید که میخواهید جلسه کاریتان چطور کار کند و لازم است متغیرها را در کدام محل قرار بدهید، اقلام را درست همانطور که ترجیح میدهید تنظیم کنید.
موقع نوشتن برنامهها -- مخصوصاً اسکریپتهای پوسته، اما این مطلب به همان اندازه برای سایر اشکال برنامهنویسی هم صدق میکند -- شخص باید از امکان بالقوه رفتار متفاوت سیستم مقصد نسبت به منطقه انتخابی، آگاه باشد.
قبلاً دیدهایم که در یک سیستم، خروجی فرمان date چگونه در واکنش به مناطق، با جابجایی فیلدها، درج کاراکترهای کامای اضافی، و زمان سنج 12 ساعتی به جای 24 ساعتی، تغییر میکند. (مورد شما ممکن است تا آن اندازه اساسی نباشد، یا حتی میتواند ریشهایتر باشد.) پیغام خطاهای برنامههای دیگر یا کتابخانههای سیستم میتوانند به سایر زبانها ترجمه شوند.
اگر شما به این استناد میکنید که خروجی برنامه یا کتابخانه فراخوانده، در یک قالب استاندارد باشد، باید برای قسمتهایی که نیاز به سازگاری دارند، متغیرهای محیط منطقه را با تنظیم منطقه به C، باطل کنید. متغیر LC_ALL دارای اولویتی برتر از متغیرهای جداگانه LC_* میباشد، که اینها نیز دارای تقدم بالاتر از متغیر LANG هستند. به این ترتیب، شما میتوانید در نقاط حساس با تحمیل LC_ALL=C ، رفتار مورد انتظارتان را به دست آورید.
مثال:
imadev:~$ echo Hello World | tr A-Z a-z hÉMMÓ wÓSMÐ imadev:~$ echo Hello World | LC_ALL=C tr A-Z a-z hello world
(این مورد همواره یکی از مثالهای مطلوب من است.)
فرمانهای بسیاری برای تعویض رفتارهای قراردادی، روشهای منطقه-مراقب، ارائه مینمایند. به عنوان مثال، tr دارای [:upper:] برای جانشینی A-Z میباشد، و نظایر آن. اینها در جایی که در دسترس هستند باید ترجیح داده شوند. در نظر بگیرید که [:upper:]میتواند مواردی مانند Á را شامل گردد که در A-Z منطقه C نخواهد بود. اما در نهایت، شما به عنوان برنامهنویس، مسئولیت انتخاب آنچه را برای پروژه شما مناسبترین است به عهده دارید.
رفتار globها نیز منطقه-مرتبط میباشد، متغیر LC_COLLATE ترتیبی را تعیین میکند که نامها براساس آن مرتب میشوند. فرمان ls نیز خروجیاش را به طور پیشفرض با استفاده از همان ترتیب وابسته به منطقه مرتب میکند. متأسفانه، روشهای استانداردی برای آموختن آنکه داخل یک منطقه مفروض کدام ترتیب به کار میرود، وجود ندارد. شخص باید به قدرت زبان بسته شگردها متوسل گردد. برای نمونه:
imadev:/tmp/greg$ for i in {1..255}; do eval touch \$\'\\x$(printf %02x $i)\'; done touch: cannot change times on / imadev:/tmp/greg$ ls -b 8 Ä C É G Î M Ò P t ü ý { - ; ¶ ¥ _ \002 \014 \026 \200 \212 \224 \236 9 ä c é g î m ò p U V ÿ } × : § ¤ \003 \015 \027 \201 \213 \225 \237 0 A Å Ç È H Ï N Ô Q u v Z « ÷ " @ µ ª \004 \016 \030 \202 \214 \226 \177 1 a å ç è h ï n ô q Ú W z » ± ¿ & ^ º \005 \017 \031 \203 \215 \227 2 Á Ã D Ê I J Ñ Ö R ú w Þ < ¬ ? ° ~ ¹ \006 \020 \032 \204 \216 \230 3 á ã d ê i j ñ ö r Ù X þ > ¼ ¡ % ´ ² \007 \021 \033 \205 \217 \231 4 À Æ Ð Ë Í K O Õ S ù x ( ` ½ ! # ¨ ³ \010 \022 \034 \206 \220 \232 5 à æ ð ë í k o õ s Û Y ) ' ¾ \ $ ¸ © \011 \023 \035 \207 \221 \233 6 Â B E F Ì L Ó Ø ß û y [ = * | ¢ · ® \012 \024 \036 \210 \222 \234 7 â b e f ì l ó ø T Ü Ý ] + , ¦ £ ¯ \001 \013 \025 \037 \211 \223 \235
این کد کاراکتر / را از قلم میاندازد چون ما نمیتوانیم فایلی با آن نام ایجاد نماییم، اما ترتیب تمام کاراکترهای دیگر درپیادهسازی HP-UX 10.20 از en_US.iso88591 را نشان میدهد. به استثنای یک مورد که من نمیتوانم آن را در محیط متنی این صفحه وب درج کنم (در محل خالی سمت چپ \003). البته، در یک کدگذاری چند بایتی مانند UTF-8 ممکن است قدری آشفتگی در آماده سازی مشاهده شود. (احتمالاً بهتر است به صورت قطعه قطعه بررسی گردد.)
چون مرتبسازی از منطقه تأثیر میپذیرد، در صورتیکه مرتبسازی سنتی برحسب ASCII را لازم داشته باشید، میتوانید ابطال LC_COLLATE را در نظر بگیرید، اما به طور کلی تا آنجا که ممکن است باید به انتخاب منطقه کاربر احترام بگذارید.
در عمل کامپیوترها نمیتوانند کاراکترها و علائم را ذخیره کنند، آنها فقط اعداد را ذخیره میکنند. روشهای بیشماری برای نمایش دادن کاراکترهای زبان انسانی( مانند حرف A، علامت به اضافه، وغیره ) به عنوان عدد، وجود دارد، و این امر که روشهای متفاوت بسیار زیادی، واقعاً به کار برده شد، به بینظمی منجر گردیده است.
کامپیوترهای اولیه (حداقل در ایالات متحده) در دو استاندارد برای طرحریزی(نگاشت) کاراکترهای US English به اعداد و بالعکس، به یکدیگر نزدیک شدند: ASCII و EBCDIC. دومی به تدریج تا اواخر قرن بیستم منسوخ گردید و ASCII ( کد استاندارد امریکایی برای تبادل اطلاعات) را به عنوان استاندارد اصلی باقی گذاشت.
مشکل با ASCII آن است که برای زبانهای غیر از انگلیسی، یا حتی برای برخی کلمات انگیسیِ وابسته به مزیتهای انشایی نویسنده، یا شاید نوشته شده با آوا نماها (به عنوان مثال rôle و naïve) خیلی محدود است. ASCII تنها بیست و شش حرف از الفبای انگلیسی (بزرگ و کوچک)، ارقام 0 تا 9، و مقداری نشانهگذاری اصلی را پوشش میدهد -- به طور معمول آنهایی که شما در صفحه کلید US کامپیوتر میبینید. در ماشینهای یونیکسی برای دیدن فهرست آنها میتوانید man ascii را تایپ کنید.
اکثر کامپیوترها از یک بایت هشت بیتی به عنوان واحد ذخیرهشان (یعنی یک دامنه از 0 تا 255 هنگامی که مانند اعداد صحیح غیر منفی بیان میشوند) استفاده میکنند. ASCII فقط کاراکترهای هفت بیتی (0 تا 127) تعریف میکند، یک میرات روزهایی که ارتباطات راه دور دادهها به طور قابل ملاحظهای آهسته و بیشتر مستعد خطا بود. چون ASCII تنها نصف محدوده یک بایت را استفاده میکند، این مطلب فضایی را برای افراد باقی گذاشت که مجموعههای کاراکتری خودشان را داخل یک بایت منفرد تعریف کنند.
(بسیاری از کاربران DOS/Windows مایکروسافت باور دارند که ASCII تمام دامنه 0 تا 255 را با صورتکهای خندان و کاراکترهای ترسیم خطوط و مانند آن را پوشش میدهد. این تصور نادرست است. مجموعه کاراکتر معروف DOS در حقیقت IBM code page 437 است، که یکی از چندین فوقمجموعه ASCII میباشد. ASCII خودش منحصر به 127 کاراکتر است.)
کاربران کامپیوتر در کشورهای خارج از US با استفاده از ASCII قادر به نمایش زبانهای نوشتاری خود نبودند، بنابراین در حالیکه برنامهنویسان US از فضای 128 تا 255 برای ایجاد کاراکترهای ترسیمی و نمادهای ریاضی استفاده میکردند، اروپاییها آنها را برای افزودن حروف اضافیشان و حروف دارای تکیه صدا به کار میبردند. این مطلب بواسطه مجموعه دیگری از استانداردهای رشد یافته یعنی ISO 8859 به بینظمی بیشتر (نه به طور تعجبآور) منجر گردید. توجه نمایید که اینها فوقمجموعههای ASCII میباشند. استاندارد ISO-8859-1 که به عنوان Latin-1 نیز شناخته میشود، استاندارد مسلط برای ایستگاههای کاری یونیکس در امریکای شمالی و غرب اروپا شد.
به هر حال، این نیز برخی موضوعات را حل نشده باقی گذاشت. نخست آنکه بازهم رقابت استانداردها وجود داشت، اروپای شرقی دارای الفبای بسیار متفاوت با اروپای غربی است، و استانداردهای متنوع ISO 8859 نیز با هم ناسازگار هستند. دوم، کشورهای آسیایی در مقایسه با کشورهای امریکایی-اروپایی دارای روشهای به طور ریشهای متفاوتی در نوشتن میباشند، و حتی مجموعه کاراکترهای آنها با فضای یک بایت منفرد (که تنها 256 علامت مختلف را مجاز میکند) مطابقت ندارد.
استاندارد Unicode تلاش دارد این مطلب را هدفگیری نماید: به جای تعریف فقط 256 علامت، هزارها نشانه تعریف میکند. اگر یک کامپیوتر باید هر علامت سندی را که از مجموعه کدهای یونیکد استفاده نموده، نمایش بدهد، به سه بایت برای هر علامت نیاز دارد، این مطلب فضای مورد نیاز برای اسناد انگلیسی ساده را نسبت به آنچه قبلاً استفاده میشد، سه برابر میسازد، که قسمت اعظم آن فضا با صفرها اشغال میشود.
بنابراین، به منظور تلاش برای حفظ برخی اثربخشیها (و همچنین بعضی سازگاریها با فایلهای دادهای موجود)، کدگذاریهای متنوعی از کاراکترهای یونیکد ایجاد گردید، در حال حاضر محبوبترینِ اینها (حداقل در میان انگلیسی زبانان) UTF-8 میباشد، که یک کدگذاری با پهنای متغییر است. یک سند اسکی(ASCII) ساده، همچنین یک سند UTF-8 معتبر نیز هست، کاراکترهای یک بایتی اسکی در UTF-8 با استفاده از همان یک بایت نمایش داده میشوند. به هرحال، UTF-8 رشتههای چندبایتی قادر به نمایش تمام کاراکترهای یونیکد را ارائه میکند (در برخی حالتها تا استفاده از چهار بایت برای هر کاراکتر).
از سال 2009، UTF-8 استاندارد نمایان برای توزیعهای لینوکس است، هرچند که بازهم مشکلات زیادی با پیادهسازیها وجود دارد.
بنابراین، «منطقه»(locale) چیست؟ چون اینهمه استانداردهای غیر معمول، و انواع مختلف کامپیوتر اینقدر زیاد وجود دارد، که برخی از آنها فقط از بعضی استانداردها پشتیبانی میکنند، اهمیت دارد که قادر باشیم بگوییم که شما در حال کار با کدام استاندارد هستید. این جایی است که مناطق از آن ناشی میشوند.
یک منطقه، مجموعه قواعدی است که تعیین میکنند اطلاعات با در نظر گرفتن انسان چگونه پردازش و نمایش داده میشود. کدگذاری کاراکترها (که در بخش اول این صفحه در باره آن صحبت کردیم) و ترتیبی که آن کاراکترها در آن مرتب میشوند، قالب نمایش تاریخ و زمان، قواعد نمایش اعداد بزرگ و اعداد با قسمت اعشاری، و غیره را پوشش میدهد.
مثالها: یک امریکایی ممکن است «روز سوم ژانویه سال 2009 میلادی» را به صورت 1/3/09 بنویسد، در حالیکه یک شخص انگلیسی ممکن است همان تاریخ را به صورت 3/1/09 بنویسد. یک برنامهنویس کامپیوتر احتمالاً 2009-01-03 را به کار خواهد برد. در ضمن دوست امریکایی ما عدد «ده هزار و یکصدم» را به شکل 10,000.01 مینویسد، بسیار آزار دهنده برای همکار آلمانیاش که به جای آن به صورت 10000,01 مینویسد.
یک سیستم یونیکس دارای فرمانی به نام locale میباشد که برای نشان دادن منطقهای که یک کاربر(یا به طور دقیقتر، یک فرایند) در لحظه مشغول استفاده از آن است، و لیست کردن تمام مناطق به کار میرود. برای مثال
imadev:~$ locale LANG=en_US.iso88591 LC_CTYPE="en_US.iso88591" LC_COLLATE="en_US.iso88591" LC_MONETARY="en_US.iso88591" LC_NUMERIC="en_US.iso88591" LC_TIME=POSIX LC_MESSAGES="en_US.iso88591" LC_ALL=
این دستور منطقهای را که در حال حاضر مورد استفاده است نشان میدهد. برای دیدن آنهایی که به جای آن میتوانند انتخاب بشوند:
imadev:~$ locale -a C POSIX C.iso88591 C.utf8 univ.utf8 ar_DZ.arabic8 ar_SA.arabic8 ar_SA.iso88596 bg_BG.iso88595 cs_CZ.iso88592 da_DK.iso88591 da_DK.roman8 nl_NL.iso88591 nl_NL.roman8 en_GB.iso88591 en_GB.roman8 en_US.iso88591 en_US.roman8 fi_FI.iso88591 fi_FI.roman8 fr_CA.iso88591 fr_CA.roman8 fr_FR.iso88591 fr_FR.roman8 de_DE.iso88591 de_DE.roman8 el_GR.greek8 el_GR.iso88597 iw_IL.hebrew8 iw_IL.iso88598 hu_HU.iso88592 is_IS.iso88591 is_IS.roman8 it_IT.iso88591 it_IT.roman8 no_NO.iso88591 no_NO.roman8 pl_PL.iso88592 pt_PT.iso88591 pt_PT.roman8 ro_RO.iso88592 ru_RU.iso88595 hr_HR.iso88592 sk_SK.iso88592 sl_SI.iso88592 es_ES.iso88591 es_ES.roman8 sv_SE.iso88591 sv_SE.roman8 th_TH.tis620 tr_TR.iso88599 tr_TR.turkish8 C.iso885915 da_DK.iso885915@euro de_DE.iso885915@euro en_GB.iso885915@euro es_ES.iso885915@euro fi_FI.iso885915@euro fr_CA.iso885915 fr_FR.iso885915@euro is_IS.iso885915@euro it_IT.iso885915@euro nl_NL.iso885915@euro no_NO.iso885915@euro pt_PT.iso885915@euro sv_SE.iso885915@euro zh_CN.hp15CN zh_TW.eucTW
در این مرحله، خواننده باید درک کند که چرا بخش نخست این صفحه به مجموعه کدگذاریهای کاراکتر اختصاص یافته بود. بدون فهم آنکه "iso885915" به چه معنا میباشد، این لیست تا اندازهای مرموز میبود.
یک نام منطقه دارای سه جزء سازنده است. بخش اول که دو حرف کوچک میباشد، زبانی را که استفاده میشود، نشان میدهد. برای مثال en به معنی انگلیسی و es اسپانیولی، de آلمانی است و به همین منوال، با استفاده از دو حرف کدهای کشوری که گویش اصلی هر زبان از آن ناشی گردیده است.
بخش دوم (پس از خط زیر) کشور واقعی که کاربر در آن است(یاآنکه کاربر میخواهد قواعد منطقه آن را به اجرا درآورد)، و اساساً برای گویشهای متفاوت یک زبان به کار میرود. en_US و en_GB دارای چند تفاوت در املای واژهها، علائم پول رایج مختلف، و مانند آن میباشند.
جزء سازنده سوم(بعد از نقطه) کدگذاری کاراکتر است. توجه نمایید که املای نام کدگذاری در میان سیستمها کاملاً استاندارد شده نمیباشد. iso885915 املای معمولی برای یک کدگذاری ISO-8859-15 میباشد، اماسیستمهای دیگر ممکن است(برای مثال) به ISO8859-15 نیاز داشته باشند. شما باید از دستور locale -a برای دیدن آنچه در سیستم شما معتبر است و چطور نوشته میشود، استفاده نمایید.
نامهای خاص C و POSIX برای این مطلب یک استثنا هستند. آنها در هرجایی لازم میشوند و مترادف هستند، آنها(به طور اساسی) به معنی «اسکی، انگلیسی US بدون اِعمال هیچ قاعده خاص» میباشند. خروجی تحت این منطقه به طور عادی با استانداردهای ISO و RFC برای تاریخ، زمان و غیره مطابقت دارد، جداکننده هزارها را کاملاً حذف میکند، از کدگذاری ASCII واقعی کمیتها برای مرتبسازی کاراکترها و مانند آن، استفاده میکند(به طور کلی با پیش فرض قرار دادن «قواعد محاسبه قراردادی US»).
شما منطقهای را که میخواهید استفاده کنید به وسیله تنظیم متغیرهای محیط تعیین میکنید. (برای بحث در باره اینکه چگونه و کجا متغیرهای محیط جهت نشستهای محاورهای خود را تنظیم کنید، صفحه DotFiles را ببینید.) متغیرهای متنوع LC_* اگر تنظیم شوند، قواعد ویژهای جهت پیروی تعریف میکنند، متغیر LANG ذخیرهای برای هر کدام از متغیرهای LC_* که تنظیم نشوند تعریف میکند. در اکثر حالتهای رایج، شما تنها LANG را تنظیم خواهید نمود.
برای به دست آوردن تنظیماتی که در مثال سیستم خود دیدیم، میتوانستیم از موردی مانند این استفاده کنیم:
imadev:~$ cat .profile ... LANG=en_US.iso88591; LC_TIME=POSIX export LANG LC_TIME ...
(توجه: فایل .profile تنها برای برخی از انواع لاگینها درست است. در صورتیکه نمیدانید به ویرایش یا ایجاد کدام فایل نیاز دارید صفحه DotFiles را ببینید.)
این مثال قواعد «US English، با کدگذاری ISO-8859-1» را برای اکثر موارد، اما قواعد POSIX را به منظور نمایش تاریخ و زمان به ما ارائه میکند.
چون اینها درست متغیرهای محیط میباشند، میتوانیم کاوش کنیم که وقتی موارد را تغییر میدهیم چه اتفاقی رخ میدهد.
imadev:~$ LC_TIME=POSIX date Thu Apr 16 10:32:03 EDT 2009 imadev:~$ LC_TIME=en_US.iso88591 date Thu, Apr 16, 2009 10:32:13 AM
برای جزئیات آنچه سیستم شما با مناطق انجام میدهد، نیاز دارید مستندات سیستم خودتان (چنین مواردی بسیار زیاد در معرض برداشت پیادهسازی کنندگان میباشد) را بررسی کنید. سیستمهای دبیان دارای locale(7) (برای خواندن آن man 7 locale را تایپ کنید)، و HP-UX دارای lang(5) میباشند و به همین ترتیب.
وقتی تعیین کردهاید که میخواهید جلسه کاریتان چطور کار کند و لازم است متغیرها را در کدام محل قرار بدهید، اقلام را درست همانطور که ترجیح میدهید تنظیم کنید.
موقع نوشتن برنامهها -- مخصوصاً اسکریپتهای پوسته، اما این مطلب به همان اندازه برای سایر اشکال برنامهنویسی هم صدق میکند -- شخص باید از امکان بالقوه رفتار متفاوت سیستم مقصد نسبت به منطقه انتخابی، آگاه باشد.
قبلاً دیدهایم که در یک سیستم، خروجی فرمان date چگونه در واکنش به مناطق، با جابجایی فیلدها، درج کاراکترهای کامای اضافی، و زمان سنج 12 ساعتی به جای 24 ساعتی، تغییر میکند. (مورد شما ممکن است تا آن اندازه اساسی نباشد، یا حتی میتواند ریشهایتر باشد.) پیغام خطاهای برنامههای دیگر یا کتابخانههای سیستم میتوانند به سایر زبانها ترجمه شوند.
در صورتیکه شما به به این استناد میکنید که خروجی برنامه یا کتابخانه مخاطب قرار گرفته در یک قالب استاندارد باشد، باید برای قسمتهایی که نیاز به سازگاری دارند، متغیرهای محیط منطقه را با تنظیم منطقه به C، باطل کنید. متغیر LC_ALL دارای اولویتی برتر از متغیرهای جداگانه LC_* میباشد، که اینها نیز دارای تقدم بالاتر از متغیر LANG میباشند. به این ترتیب، شما میتوانید در نقاط حساس با تحمیل LC_ALL=C ، رفتار مورد انتظارتان را به دست آورید.
مثال:
imadev:~$ echo Hello World | tr A-Z a-z hÉMMÓ wÓSMÐ imadev:~$ echo Hello World | LC_ALL=C tr A-Z a-z hello world
(این مورد همواره یکی از مثالهای مطلوب من است.)
فرمانهای بسیاری برای تعویض رفتارهای قراردادی، روشهای منطقه-مراقب، ارائه مینمایند. به عنوان مثال، tr دارای [:upper:] برای جانشینی A-Z میباشد، و نظایر آن. اینها در جایی که در دسترس هستند باید ترجیح داده شوند. در نظر بگیرید که [:upper:] ممکن است مواردی مانند Á را که در A-Z منطقه C نخواهد بود را شامل گردد. اما در نهایت، شما به عنوان برنامهنویس، مسئولیت انتخاب آنچه برای پروژه شما مناسبترین است را به عهده دارید.
رفتار globها نیز منطقه-مرتبط میباشد، متغیر LC_COLLATE ترتیبی را تعیین میکند که نامها براساس آن مرتب میشوند. فرمان ls نیز خروجیاش را به طور پیشفرض با استفاده از همان ترتیب منطقه-مرتبط مرتب میکند. متأسفانه، روشهای استانداردی برای آموختن آنکه داخل یک منطقه مفروض کدام ترتیب به کار میرود، وجود ندارد. شخص باید به قدرت زبان بسته شگردها متوسل گردد. برای نمونه:
imadev:/tmp/greg$ for i in {1..255}; do eval touch \$\'\\x$(printf %02x $i)\'; done touch: cannot change times on / imadev:/tmp/greg$ ls -b 8 Ä C É G Î M Ò P t ü ý { - ; ¶ ¥ _ \002 \014 \026 \200 \212 \224 \236 9 ä c é g î m ò p U V ÿ } × : § ¤ \003 \015 \027 \201 \213 \225 \237 0 A Å Ç È H Ï N Ô Q u v Z « ÷ " @ µ ª \004 \016 \030 \202 \214 \226 \177 1 a å ç è h ï n ô q Ú W z » ± ¿ & ^ º \005 \017 \031 \203 \215 \227 2 Á Ã D Ê I J Ñ Ö R ú w Þ < ¬ ? ° ~ ¹ \006 \020 \032 \204 \216 \230 3 á ã d ê i j ñ ö r Ù X þ > ¼ ¡ % ´ ² \007 \021 \033 \205 \217 \231 4 À Æ Ð Ë Í K O Õ S ù x ( ` ½ ! # ¨ ³ \010 \022 \034 \206 \220 \232 5 à æ ð ë í k o õ s Û Y ) ' ¾ \ $ ¸ © \011 \023 \035 \207 \221 \233 6 Â B E F Ì L Ó Ø ß û y [ = * | ¢ · ® \012 \024 \036 \210 \222 \234 7 â b e f ì l ó ø T Ü Ý ] + , ¦ £ ¯ \001 \013 \025 \037 \211 \223 \235
این کد کاراکتر / را از قلم میاندازد چون ما نمیتوانیم فایلی با آن نام ایجاد نماییم، اما ترتیب تمام کاراکترهای دیگر درپیادهسازی HP-UX 10.20 از en_US.iso88591 را نشان میدهد. به استثنای یک مورد که من نمیتوانم آن را در محیط متنی این صفحه وب درج کنم (در محل خالی سمت چپ \003). البته، در یک کدگذاری چند بایتی مانند UTF-8 ممکن است قدری آشفتگی در آماده سازی مشاهده شود. (احتمالاً بهتر است به صورت قطعه قطعه بررسی گردد.)
چون مرتبسازی از منطقه تأثیر میپذیرد، در صورتیکه مرتبسازی سنتی برحسب ASCII را لازم داشته باشید، شاید ابطال LC_COLLATE را در نظر بگیرید، اما به طور کلی تا آنجا که ممکن است باید به انتخاب منطقه کاربر احترام بگذارید.