У меня установлен Ruby 3.3.4 на MacOS 14.6.1.
Предположим, у меня есть эта строка в оболочке:
$ st = "0😀2☺️4🤪6🥳8🥸"
$ echo "$st"
0😀2☺️4🤪6🥳8🥸
Если я теперь передам эту строку в Ruby, я получу второй смайлик, разбитый на составные части:
$ echo "$st" | ruby -lne 'p $_.split("")'
["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸"]
^ ^ # should be ONE grapheme
То же самое, если я прочитаю эту строку из файла:
$ cat wee_file
0😀2☺️4🤪6🥳8🥸
$ ruby -lne 'p $_.split("")' wee_file
["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸"]
То же самое и в IRB:
irb(main):001> File.open('/tmp/wee_file').gets.split("")
=> ["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸", "\n"]
Но если я заменю ☺️ другим эмодзи (который тоже многобайтовый), проблема исчезнет:
$ st2 = "0😀2🐱4🤪6🥳8🥸"
$ echo "$st2" | ruby -lne 'p $_.split("")'
["0", "😀", "2", "🐱", "4", "🤪", "6", "🥳", "8", "🥸"]
# also from a file and also in IRB..
Есть идеи, почему смайлик ☺️ дает такой результат?
🤔 А знаете ли вы, что...
Ruby имеет множество фреймворков для разработки игр и визуализации данных.
Это потому, что ☺️ состоит из двух символов:
☺
U+263A (Белое улыбающееся лицо)◌️
U+FE0F (Выбор варианта-16)Последний используется для запроса представления смайликов для предыдущего персонажа.
"☺️".codepoints.map { |c| c.to_s(16) }
#=> ["263a", "fe0f"]
Вы можете получить ожидаемый результат с помощью grapheme_clusters или перечислить их с помощью each_grapheme_cluster :
"0😀2☺️4🤪6🥳8🥸".grapheme_clusters
#=> ["0", "😀", "2", "☺️", "4", "🤪", "6", "🥳", "8", "🥸"]