LINUX.ORG.RU
ФорумTalks

Факап на факапе

 , ,


0

1

Приложения для линукс — неиссякающий источник еды. Итак, дано: идея написать плагин-калькулятор на Lua для medit. Надо сказать, про Lua я не знаю ровным счётом ничего. Открываю мануалы на Lua и на API редактора, начинаю писать.

line_nr = doc.get_line_at_cursor()
cur_line_end = doc.get_pos_at_line_end(line_nr)
doc.set_cursor_pos(cur_line_end)
doc.insert_text("\n")

text = doc.get_line_text(line_nr)
f = loadstring("return (" .. text .. ")")
result = tostring(f())
doc.insert_text(result)

Проверяем:

20/4
5
Ок.
21/4
5,25
Не ок! Используется десятичный разделитель из локали. А должен — десятичный разделитель ЯП, чтобы потом это число можно было снова интепретатору скормить.

Проверяем:

> os.setlocale("C")
> print(tostring(1.5))
1.5
> os.setlocale("ru_RU.UTF-8")
> print(tostring(1.5))
1,5
Мда.

Копаем сорцы. Находим, что tostring работает через sprintf. sprintf использует десятичный разделитель локали. Курю man sprintf на предмет принудительного использования точки в качестве разделителя. Ничего не накуриваю.

Думаю, ладно — хрен с тобой, золотая рыбка. Подменю локаль прямо в скрипте. Пишем:

line_nr = doc.get_line_at_cursor()
cur_line_end = doc.get_pos_at_line_end(line_nr)
doc.set_cursor_pos(cur_line_end)
doc.insert_text("\n")

text = doc.get_line_text(line_nr)
f = loadstring("return (" .. text .. ")")
result = f()

old_locale = os.setlocale(nil)
os.setlocale("C")

result = tostring(result)

os.setlocale(old_locale)

doc.insert_text(result)

И-и-и-и... обламываюсь! Потому что объект os в API medit-а не входит.

Вот прям даже не знаю, куда репортить это нелепое стечение обстоятельств. Наверное всё-таки в Lua. Ибо какого черта они не дали готовой функции для локаленезависимого преобразования чисел в строки.

Факап

язабан.

чтобы потом это число можно было снова интепретатору скормить.

потому что у тебя сейчас сделано тупо строку запихиваешь, как я понял без разбора.
а если оччень надо, то тогда регулярками заменяешь ',' между числами на '.' .

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

потому что у тебя сейчас сделано тупо строку запихиваешь, как я понял без разбора.

А нах мне его разбирать, когда есть няшный loadstring()?

а если оччень надо, то тогда регулярками заменяешь ',' между числами на '.' .

Ты вообще в курсе, что такое локаль? Предлагаешь мне извлекать из настроек локали десятичный разделитель и понять регулярку? Это даже не зубы рвать автогеном через задницу, это еще круче. И да — всё это извращение всё-равно не получится, потому API урезан, сказано же.

geekless ★★
() автор топика
Ответ на: комментарий от geekless

Предлагаешь мне извлекать из настроек локали десятичный разделитель

Всегда заменять запятую между числами на точку, при любой локали.

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

А вот нихрена, пользователь мог ввести выражение, вычисляющееся в строку, содержащую запятые. Придётся еще проверку типа ставить:

если (результат число)
{
  результат = заменить_запятую(tostring(результат))
}

geekless ★★
() автор топика
Ответ на: комментарий от dmfd

Результат уже иной. Хоть и не верный, но движение есть — это хорошо.
Продолжай думать, не останавливайся, глядишь додумаешь до чего-то дельного.

Bad_ptr ★★★★★
()

а на кой локаль то менять?

ggrn ★★★★★
()
Ответ на: комментарий от geekless

Не, я не понял. loadstring — это типа eval ? Т.е. строка вычисляется как луа-код? Дак вот перед запихиванием в этот лоадстринг и убирай запятые, а при выводе результата запятые можешь оставить.
Или я чего-то не понимаю... :(

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

Дак вот перед запихиванием в этот лоадстринг и убирай запятые

Всё-таки dmfd выше был прав. Я за бан.

math.pow(2,4.5)

Убирай запятые, ага.

geekless ★★
() автор топика

А почему у меня в интерпретаторе луы 5.2 в убунте следующее:

$ lua
Lua 5.2.0  Copyright (C) 1994-2011 Lua.org, PUC-Rio
> print(tostring(21/5))
4.2
> 
$ echo $LC_NUMERIC 
ru_RU.utf8
PolarFox ★★★★★
()
Ответ на: комментарий от geekless

math.pow(2,4.5)
Убирай запятые, ага.

Убирать запятые, только если не в вызове функции :)

Bad_ptr ★★★★★
()
Ответ на: комментарий от PolarFox

И даже более того, print(«2,1» + «3,7») вывело 5,8.

PolarFox ★★★★★
()

А что было бы, если бы стояла задача написать что-то сложнее кулькулятора?

Там наверное пришлось бы сделать пару сотен патчей на ядро?

Munhgauzen
()
Ответ на: комментарий от PolarFox

А какая разница, кошерно или нет — запятую всё-равно не получится использовать как десятичный разделитель. Она нужна для вызова функций. Даже если я интерпретатор вручную напишу.

Ну и еще возникает вопрос, как в этом языке сделать проверку isnumber. Функция lua_isnumber() только в C API вынесена, в самом языке соответствующей функции isnumber() что-то не видно.

geekless ★★
() автор топика

Ок, вот такая штука получилось:

line_nr = doc.get_line_at_cursor()
cur_line_end = doc.get_pos_at_line_end(line_nr)
doc.set_cursor_pos(cur_line_end)
doc.insert_text("\n")

text = doc.get_line_text(line_nr)
f = loadstring("return (" .. text .. ")")
result = f()

if type(result) == "number" then
	result = string.gsub(tostring(result), ",", ".", 1)
end

doc.insert_text(result)

geekless ★★
() автор топика

Вот прям даже не знаю, куда репортить это нелепое стечение обстоятельств. Наверное всё-таки в Lua.

Лучше бы не парился и не использовал всякие кривые поделки, типа Lua. Не работает - не твои проблемы.

Siado ★★★★★
()
Ответ на: комментарий от Siado

он не кривой, его очень удобно встраивать и писать на нем плагины. Надо научиться на нём программировать, прежде чем его ругать.

XVilka ★★★★★
()
Ответ на: комментарий от XVilka

он не кривой, его очень удобно встраивать и писать на нем плагины

Почему в некривом языке нет даже функции сериализации примитивных типов данных, совместимой с собственным парсером ЯП?

geekless ★★
() автор топика
Ответ на: комментарий от geekless

тогда не в курсе, я калькулятор на си писал, потом в lua экспортировал (использование eval() - все-таки очень опасная штука)

XVilka ★★★★★
()

1,5

Эпично. А что, какого-нибудь сырого принта в lua нет?

buddhist ★★★★★
()
Ответ на: комментарий от wwwsevolod

Не могу представить, чем он может быть приятен. А в наше время его вообще не вижу смысла использовать, есть гораздо более перспективные технологии.

Siado ★★★★★
()
Ответ на: комментарий от XVilka

он не кривой, его очень удобно встраивать и писать на нем плагины. Надо научиться на нём программировать, прежде чем его ругать.

Из разряда «Дельфи не кривой - сперва научись на нем программировать»

Siado ★★★★★
()
Ответ на: комментарий от XVilka

В любом случае луашники либо так же отвечают, либо городят неведомы костыли =)

Siado ★★★★★
()
Ответ на: комментарий от Siado

Из этого списка лишь lua и (в некоторой степени) жабаскрипт удобны для встраиваемого кода.

upd: и это при том, что lua — по сути тот же жабаскрипт с уменьшенным числом wtf.

PolarFox ★★★★★
()
Последнее исправление: PolarFox (всего исправлений: 1)
Ответ на: комментарий от Siado

Java, C#, PHP - не лучшая идея для встраивания. Остается Ruby, но он достаточно медленный, Lisp/Scheme - мало программистов на нем, высокий порог вхождения, Python - неплох, его тоже использую. Haskell - неплох, но по сути нет встраивания. Все остальное - специфические языки, для своих сфер. Lua - быстр (luajit/luaffi), легок (можно статически компилировать), легок для изучения.

XVilka ★★★★★
()
Ответ на: комментарий от x3al

Поставь локаль fa_IR.UTF-8 и повтори свой фокус.

Ну так а хрен ли делать-то.

Нормальная функция перевода числа в строку получится больше, чем сам этот скрипт.

geekless ★★
() автор топика
Ответ на: комментарий от x3al

Всегда отрывать руки за это. Потому, что.

ок.

//P.S.: Но это же опенсорс! У кого не заработает, тот сам доработает скрипт (: .

Bad_ptr ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.