Страница 1 из 2

языковая локализация в программном коде

Добавлено: 07 дек 2022, 14:55
Olej
Эта тема возникла как продолжение вот этого: Локализация и регулярные выражения, C/C++
...
темы здесь в форуме:
локализация строк в C-коде (последняя запись 22 дек 2017)
регулярные выражения в C/C++ (последняя запись 12 дек 2017)
Я это написал (окончательно) где-то к 2018 году ... и как-то забыл отметить здесь в форуме объявлением:
Локализация в коде C/C++
Регулярные выражения и локализация в коде C/C++

Изначально это появилось в моём блоге - сентябрь 2016 - как:
* Языковая локализация C/C++
* Регулярные выражения C/C++
Эти 2 статьи представлены с архивами кодов к ним.
Но новый интерес к этому всему возник из желания единым подходом посмотреть бегло как эти дела состоят в других (не C/C++) современным, более новых языках программирования: Python, Go, Rust, Kotlin …

Re: языковая локализация в программном коде

Добавлено: 08 дек 2022, 14:28
Olej
Olej писал(а):
07 дек 2022, 14:55
Эта тема возникла как продолжение
Интересно, что по локализации программного кода, C/C++ и вообще всех языков, крайне мало литературы, если сравнивать вообще с самим описанием языка...
Это из моего предыдущего текста:
• сам тип локализованных символов (wchar_t) появился в стандарте C89, но, в полной мере с API поддержки и т.п., только в стандарте C99 ... относительно недавно (по крайней мере, недавно, в сравнении с 45-летней историей C);
• и, конечно, этот тип и всё, что связано с локализацией, не может даже упоминаться в классической литературе по C периода его становления: K&R и т.п.;
• все более поздние книги и учебники по C, те которые переводные, тоже практически полностью обходят эту тему стороной ... их англоязычным авторам она совершенно не интересна, не близка — оно им не актуально ... да они и сами этой части языка просто слабо знают с ней не пересекаясь;
• отечественные же, русскоязычные учебники (а здесь встречаются только учебные книги по C, для студентов университетов, например ... кто же станет писать "не-учебник" по столь древнему языку?) — здесь авторы-педагоги, не являющиеся практиками программной разработки, сами также, главным образом, переписывают и пересказывают материал из англоязычных изданий ... ну, ещё придумают десяток собственных примеров кода; но раз в первоисточниках этого нет, то его и вообще нет в природе;
• далеко не последнюю роль (а может даже ведущую) сыграло то обстоятельство, что последние 25-30 лет основная масса русскоязычных практикующих программистов работали успешно подавляющим образом в аутосорсинге, на зарубежных заказчиков, где вопросы локализации не стояли;
Но сейчас то ситуация должна меняться! :-?
• в связи с требованиями и объёмами импортозамещения и создания оригинального локализованного программного обеспечения;
• а также из-за свежих законодательных требований по использованию отечественных операционных систем, все они из которых являются теми или иными клонами Linux (другим неоткуда взяться).

Это мотивация нового пересмотра старого материала...

Re: языковая локализация в программном коде

Добавлено: 08 дек 2022, 14:31
Olej
Olej писал(а):
08 дек 2022, 14:28
Это мотивация нового пересмотра старого материала...
И сюда же буду прикреплять архивы кодов, по мере их изменения по ходу... А то уже сам начинаю терять бывшие наработки.
Это начальное приближение:

Re: языковая локализация в программном коде

Добавлено: 09 дек 2022, 03:22
Olej
Olej писал(а):
07 дек 2022, 14:55
Но новый интерес к этому всему возник из желания единым подходом посмотреть бегло как эти дела состоят в других (не C/C++) современным, более новых языках программирования: Python, Go, Rust, Kotlin …
Все новые языки декларируют, что в них всё представляется в кодировке UTF-8.
Но это следует проверять, как и то до какой степени это "всё".

Re: языковая локализация в программном коде

Добавлено: 09 дек 2022, 03:26
Olej
Olej писал(а):
09 дек 2022, 03:22
Все новые языки декларируют, что в них всё представляется в кодировке UTF-8.
Python ...

В Python версии 2, бывшим превалирующим (в Linux) на протяжении около 20 лет не было соглашений о дефаултной локали в коде:

Код: Выделить всё

$ python2
Python 2.7.18 (default, Jul  1 2022, 12:27:04)
[GCC 9.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale()
(None, None)
Для указания использования кодировки UTF-8 требовалось явное указание этого (2-я строка):

Код: Выделить всё

$ cat l2.1.py 
#!/usr/bin/python2
# -*- coding: utf-8 -*-
print("русскоязычная строка")

$ ./l2.1.py
русскоязычная строка
Но стоит вам убрать эту строку спецкомментария, и интерпретатор теряется и не знает что делать с такой Unicode строкой:

Код: Выделить всё

$ cat l2.2.py 
#!/usr/bin/python2
print("русскоязычная строка")

$ ./l2.2.py
  File "./l2.2.py", line 2
SyntaxError: Non-ASCII character '\xd1' in file ./l2.2.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
Но по стандарту Python версии 3 (начавшим распространение с 2008 года и с 2022 года ставшим, наконец, стандартом по умолчанию для основных дистрибутивов Linux - см. Python: версии языка) регламентируется что всё в коде представляется в кодировке UTF-8. Сравните:

Код: Выделить всё

$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale()
('ru_UA', 'UTF-8')
И теперь для мультиязычных приложений нет сложностей в этом смысле, и не нужны никакие дополнительные явные указания:

Код: Выделить всё

$ cat l3.1.py
#!/usr/bin/python3
print("русскоязычная строка")
print("Hello, 世界")

$ ./l3.1.py
русскоязычная строка
Hello, 世界
Более того, и в самом коде (который также представляется в UTF-8) могут использоваться мультиязычные символы, например в именах переменных для большей ясности их значений:

Код: Выделить всё

$ python3
Python 3.8.10 (default, Nov 14 2022, 12:59:47) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> длина = 123
>>> print(длина)
123

Re: языковая локализация в программном коде

Добавлено: 09 дек 2022, 03:39
Olej
Olej писал(а):
09 дек 2022, 03:26
в самом коде (который также представляется в UTF-8) могут использоваться мультиязычные символы, например в именах переменных для большей ясности их значений
Или, если угодно, так:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ cat l3.2.py 
#!/usr/bin/python3
import sys

def рекурсивная_функция_фибоначчи(n) :
    if n < 2 : return 1
    else: return рекурсивная_функция_фибоначчи(n - 1) + рекурсивная_функция_фибоначчи(n - 2)

n = int(sys.argv[1])
print("{}".format(рекурсивная_функция_фибоначчи((int(sys.argv[1])))))

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ ./l3.2.py 20
10946

Re: языковая локализация в программном коде

Добавлено: 10 дек 2022, 23:36
Olej
Olej писал(а):
09 дек 2022, 03:26
Python
Дальше Go ...
Язык Go был официально представлен в 2009 году, поэтому он, естественно1, изначально ориентирован на использование во всём кодировки UTF-8. Что совершенно естественно, учитывая что один из основных разработчиков Go Роб Пайк — был, в своё время, и разработчиком кодировки UTF-8.

Совершенно естественно, что все символьные константы в Go представлены в Unicode в кодировке UTF-8 (и на вводе и выводе с периферийными устройствами, терминалом). Но, более того, сама запись кода Go хранится в UTF-8, и допускает мультиязычные имена объектов в коде программы.

Re: языковая локализация в программном коде

Добавлено: 10 дек 2022, 23:41
Olej
Olej писал(а):
10 дек 2022, 23:36
Дальше Go
Парочка примеров (больше и добавить нечего, всё ясно):

Код: Выделить всё

$ cat hello.go
package main
import ("fmt", "os")

func main() {
        fmt.Println("ты кто будешь?")
        fmt.Printf("> ")
        буфер := make([]byte, 120)
        длина, _ := os.Stdin.Read(буфер) // возвращается 2 значения
        Ω := длина
        ответ := string(буфер[:Ω-1]) // убрали '\n'
        fmt.Printf("какое длинное имя ... целых %d байт\n", Ω)
        fmt.Printf("привет, %s\n", ответ)
}

Код: Выделить всё

$ go run hello.go 
ты кто будешь?
> Йося
какое длинное имя ... целых 9 байт
привет, Йося
Обращаем внимание на то как Go считает длину введенной текстовой строки: байты но не символы!
И 2-й пример:

Код: Выделить всё

$ cat circle.go
package main
import ("fmt"; "os"; "math"; "strconv")

var π float64 = math.Pi

func main() {
    bufer := make([]byte, 80)
    for {
        fmt.Printf("радиус вашего круга? : ")
        длина, _ := os.Stdin.Read(bufer)
        str := string(bufer[:длина-1])
        if 0 == len(str) { break };
        радиус, err := strconv.ParseFloat(str, 64)
        if err != nil {
            fmt.Println("ошибка ввода!")
            continue
        }
        fmt.Printf("длина окружности 2*π*радиус = %f\n",
            2*π*радиус)
    }
}

Код: Выделить всё

$ go run circle.go
радиус вашего круга? : 10
длина окружности 2*π*радиус = 62.831853
радиус вашего круга? :
Функция len() для строки также возвращает число байт, но не символов. Если же мы захотим получить число символов, в нашем понимании, мы должны проделать некоторое преобразования, например так: utf8.RuneCountInString(str).

Re: языковая локализация в программном коде

Добавлено: 11 дек 2022, 01:01
Olej
Olej писал(а):
10 дек 2022, 23:41
Дальше Go
Дальше Rust ...
Язык программирования Rust — компилируемый и мультипарадигмальный, позиционируется многими как альтернатива С/С++. Язык был официально представлен в 2010 году. Символьный (char) тип Rust (один из «простых» типов), представляет символ Unicode (внутреннее представление данных как u32). Строка (как ещё один тип данных) гарантированно является корректной последовательностью байтов с точки зрения UTF-8 (это фраза из документации Rust).

Для этого варианта следует ожидать мультиязыковую поддержку без всяких проблем... Что и проверим:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ cat mullang.rs
fn greet_world() {
    let regions = [
        String::from("السلام عليكم"),
        String::from("Dobrý den"),
        String::from("Hello"),
        String::from("שָׁלוֹם"),
        String::from("नमस्ते"),
        String::from("こんにちは"),
        String::from("안녕하세요"),
        String::from("你好"),
        String::from("Olá"),
        String::from("Здравствуйте"),
        String::from("Hola"),
    ];

    for region in regions.iter() {
        println!("{}", &region);
    }
}

fn main() {
    greet_world();
}
Компиляция:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ rustc mullang.rs

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ ls -l mullang*
-rwxrwxr-x 1 olej olej 3911360 дек 10 22:46 mullang
-rw-r--r-- 1 olej olej     588 ноя  2 23:35 mullang.rs

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ file mullang
mullang: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d1da0012535cf77bcbeb9a5e9018612d6e8e28fb, for GNU/Linux 3.2.0, with debug_info, not stripped
Выполнение:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/localiz.cod$ ./mullang
السلام عليكم
Dobrý den
Hello
שָׁלוֹם
नमस्ते
こんにちは
안녕하세요
你好
Olá
Здравствуйте
Hola
Замечательно :!: :-D

Re: языковая локализация в программном коде

Добавлено: 11 дек 2022, 01:06
Olej
Olej писал(а):
11 дек 2022, 01:01
Замечательно
Остаётся интерес к тому как Rust отнесётся к объектам в коде, именованных в национальных символах в кодировке UTF-8:

Код: Выделить всё

$ cat utf8rs.rs 
fn main() {
    let строка = "строка";
    println!("вывод: {}", &строка);

    let 안녕하세요 = "안녕하세요";
    println!("вывод: {}", &안녕하세요);
}
Здесь компиляция завершится с обильными предупреждениями:

Код: Выделить всё

$ rustc utf8rs.rs
warning: the usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables
  --> utf8rs.rs:19:9
   |
19 |     let строка = "строка";
   |         ^^^^^^
   |
   = note: `#[warn(mixed_script_confusables)]` on by default
   = note: the usage includes 'а' (U+0430), 'к' (U+043A), 'о' (U+043E), 'р' (U+0440), 'с' (U+0441), 'т' (U+0442)
   = note: please recheck to make sure their usages are indeed what you want

warning: 1 warning emitted
Но это только предупреждения, и код компилируется и успешно выполняется:

Код: Выделить всё

$ ls -l utf8rs
-rwxrwxr-x 1 olej olej 3888344 ноя  2 19:30 utf8rs

$ ./utf8rs
вывод: строка
вывод: 안녕하세요
Только хотелось бы избавиться от многочисленных предупреждений, если мы делаем это сознательно. Достигается это использованием одной из многочисленных прагм Rust (mixed_script_confusables):

Код: Выделить всё

$ cat utf8rs.rs 
#![allow(mixed_script_confusables)]

fn main() {
    let строка = "строка";
    println!("вывод: {}", &строка);

    let 안녕하세요 = "안녕하세요";
    println!("вывод: {}", &안녕하세요);
}
И теперь это выглядит так - всё становмтся чисто:

Код: Выделить всё

$ rustc utf8rs.rs

$ ./utf8rs
вывод: строка
вывод: 안녕하세요