Сначала маленькое неприятное, но понятное наблюдение: 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 беспроблемный код.
Комментариев нет:
Отправить комментарий