===[ Ruby / Windows ]=== #post-id: 5475-22-27 #original-date: 23.07.2015 Thu #original-time: 10:27 PM #original-day: 5475 #original-host: WinXP Home SP3 (Build 2600) Ruby хочет аргументы командной строки в UTF-8. Они там охренели что ли? #upd: Всвязи с тем, что данный пост в пойнтожуйках стал детектором идиотов, стоит дать пояснения для толстолобиков. http://juick.com/Linda-chan/2795604 http://linda-chan.point.im/vyqmf Сработали триггеры. Увидел человек "UTF-8", вспомнил, что UTF-8 вроде как где-то там "стандарт" и вообще все текстовые файлы в нём, и ринулся нести свет истины. Увидел другой человек "Ruby" и начал доказывать, что это кроссплатформенный софт, а значит не должен работать на всех поддерживаемых платформах правильно. Вспомнил третий человек, что Руби - это что-то про консоль, и тут же безапеляционно заявил, что CMD "не поддерживает" Юникод, и PoSH обязательно поможет. Кому-то даже примерещились "потоки байтов из интернета". А кто-то, вспомнив предыдущий пост про сайт на Руби с Хамлом, подумал, что тэг "Windows" - это всё равно "Linux", поскольку сайт же. О чём всё это говорит? Это говорит о том, что люди - идиоты, не способные прочитать пост, прочитать тэги и осознать то, о чём в нём говорится. Зато горазды броситься в спор, обосраться и потом писать посты про то, как их оскорбляли, унижали и вообще ранили душу. Ну или типа успешно троллить. Так вот, суть проблемы. В Windows для запуска процесса используется функция CreateProcess() (которая на самом деле вызывает CreateProcessAsUser()), в которую передаются всякие нужные сведения в том числе и командная строка программы. Поскольку у NT юникодное ядро, и используется UTF-16, то командная строка передаётся именно в этой кодировке. Как вариант - ANSI версия функции, которая всё равно конвертирует ANSI строку в UTF-16 и вызывает юникодную версию функции. Когда новый процесс стартует, он может посмотреть собственную командную строку функцией GetCommandLine(), которая возвращает командную строку, переданную при запуске в виде строки UTF-16. ANSI версия берёт эту строку, конвертирует в ANSI, и возвращает программе. Легко заметить, что здесь, несмотря на использование юникода, нигде не всплывает UTF-8 ни в каком виде. Тем не менее, программа Ruby.exe (которая и есть исполняемый модуль всего этого дела), принимая параметры при запуске, почему-то считает, что это UTF-8. Не знаю, какую версию функции GetCommandLine() она использует (ANSI или Unicode), но без всякой конвертации полученное значение отправляется во внутренние структуры, разбирается как UTF-8. Если в командной строке оказываются имена файлов с русскими буквами, то первая же попытка их найти приводит к закономерному провалу. Самое здравое решение - кинуть симлинк на папку с исходниками так, чтобы с получившемся пути не было русских букв. А сами файлы переименовать, если нужно. Самое идиотское решение - городить целую виртуальную машину в линупсом на борту только для того чтобы выполнить скрипт на пару строк. Рациональное решенние, да. Звучала мысль, что де это норма для кроссплатформенного софта, он весь ждёт только UTF-8 из командной строки etc. При этом вокруг себя я наблюдаю кучу такого софта, который прекрасно понимает русский язык в командной строке, а значит не ждёт никакого UTF-8 на входе, там где его быть не может. Звучала мысль, что CMD не поддерживает Юникод. К сожалению телепаты провалились, поскольку запуск происходил из юникодного FAR. Ну а "потоки байтов из интернета" при локальном запуске екзешника с локальным файлом я комментировать даже не буду.