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

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 07 дек 2022, 14:55

Эта тема возникла как продолжение вот этого: Локализация и регулярные выражения, 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 …

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 08 дек 2022, 14:28

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

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 08 дек 2022, 14:31

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 09 дек 2022, 03:22

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 09 дек 2022, 03:26

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 09 дек 2022, 03:39

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
Вложения
python.tgz
(458 байт) 27 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 10 дек 2022, 23:36

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

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 10 дек 2022, 23:41

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).
Вложения
circle.go
(520 байт) 27 скачиваний
hello.go
(442 байт) 27 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 11 дек 2022, 01:01

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
Вложения
mullang.rs
(581 байт) 27 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

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

Непрочитанное сообщение Olej » 11 дек 2022, 01:06

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
вывод: строка
вывод: 안녕하세요
Вложения
utf8rs.rs
(233 байт) 38 скачиваний

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя