Это именно то, как это определено в MRI, более конкретно в функции rb_ensure
в eval.c (я рассмотрел фактическую реализацию, но по сути она просто генерирует контекст выполнения Ruby, выполняетблокировать в этом контексте, а затем убедиться, что все ensure
блоки выполняются один за другим:
* Equivalent to <code>begin .. ensure .. end</code>.
*
* Calls the function \a b_proc with \a data1 as the argument,
* then calls \a e_proc with \a data2 when execution terminated.
* \return The return value of \a b_proc if no exception occurred,
* or \c Qnil if otherwise.
* \sa rb_rescue
* \sa rb_rescue2
* \sa rb_protect
* \ingroup exception
*/
VALUE
rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
{
...
}
Если вам интересно, как синтаксический анализатор решит вызвать эту фракцию, посмотрите на parse.y
это часть правил для bodystmt
.