суббота, 8 июня 2013 г.

Чего-то я не понимаю в этом вашем rb_protect...

Сначала маленькое неприятное, но понятное наблюдение: rb_eval_string_protect() в Ruby 1.9 (и, надо полагать, в 2.0 тоже) воспринимает эту самую «string» как содержащую данные в кодировке US-ASCII. Собственно, так поступают все фунции работы со строками, унаследованные из 1.8, но для обычного преобразования строки в ruby-объект String есть новые функции, позволяющие кодировку указать. А для rb_eval_string_protect() соответствующих аналогов не предусмотрено...

Отсюда логичное желание сначала строку преобразовать (с указанием правильной UTF-8), а затем уже выполнить — скормить методу Kernel.eval(). Заворачиваем этот вызов в функцию, вызываем ее через rb_protect()... И получаем странную вещь — все вроде бы отрабатывается, но если в Ruby происходит исключение, рушится стек исключений уже внешнего pascal-кода. При успешном вызове такого не происходит. Возможно, где-то косяк с соглашениями о вызове — си-паскаль переходы штука тонкая, да... Но: а) любые действия, не вызывающие исключения, проходят на ура, многократно и т.д., т.е. стек вызовов, в отличие от стека исключений, в порядке, и б) ruby-методы, мною созданные из pascal-функций, с теми же соглашениями о вызовах, работают правильно...

Причем, rb_eval_string_protect() работает прекрасно — корректно обрабатывает исключения, как и должно быть по документации. Только о кодировках ничего не знает, а так — ok. В общем, сейчас рабочий вариант такой — задаю глобальную переменную «$script_string», а затем через rb_eval_string_protect() выполняю «eval $script_string». Само по себе это решение меня устраивает, но непонятки с rb_protect() все-таки напрягают.

PS. Для иллюстрации: проблемный код vs беспроблемный код.

Комментариев нет:

Отправить комментарий