💡 Инструкция: Выберите один ответ из пяти. Время — 55 минут. У каждого задания ровно один правильный вариант. Фрагменты рассчитаны на Ruby 4.0.6; задания Rails — на Rails 8.1.3. После завершения откроются общий процент, 4 тематических результатов и разбор всех ответов.
Вопрос 1 из 20
Как изменится состояние программы после выполнения кода по теме «Передача блока»? Правильным считается только полностью согласованное утверждение.
Ruby Ruby — Передача блока Копировать
# Проследите выполнение и выберите точный результат.
def twice(value, &block)
block.call(block.call(value))
end
p twice(3) { |n| n + 2 }
Метод дважды вызывает переданный блок через `call`, поэтому результат равен 7. Это объясняется тем, что блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока.
Lambda с одним параметром и двумя аргументами поднимает ArgumentError до выполнения тела. Это объясняется тем, что блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока.
Метод дважды вызывает переданный блок через `call`, поэтому результат равен 7. Это объясняется тем, что `yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`.
Метод дважды вызывает переданный блок через `call`, поэтому результат равен 7. Это объясняется тем, что блок захватывает привязки из лексического окружения, поэтому может читать и изменять внешнюю локальную переменную после создания.
Два вызова счётчика возвращают 1 и 2: замыкание хранит одну и ту же привязку `count`. Это объясняется тем, что блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока.
Вопрос 6 из 20
Какое допущение делает этот код по теме «Вызов блока через yield» ненадёжным? Сопоставьте не только итог, но и правило, риск или проверку, которые с ним связаны.
Ruby Ruby — Вызов блока через yield Копировать
# Обычный запуск проходит. Найдите скрытый риск.
def transform(value)
return value unless block_given?
yield(value) * 3
end
p transform(4) { |n| n }
p transform(4)
Без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта. Этот риск связан с тем, что `yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`.
Замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод. Этот риск связан с тем, что `yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`.
Без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код. Этот риск связан с тем, что блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока.
Без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код. Этот риск связан с тем, что блок захватывает привязки из лексического окружения, поэтому может читать и изменять внешнюю локальную переменную после создания.
Без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код. Этот риск связан с тем, что `yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`.
Вопрос 7 из 20
Обычный сценарий проходит. Какой риск остаётся в теме «Различия Proc/lambda»? Проверьте обе половины ответа: частично верный вариант остаётся неверным.
Ruby Ruby — Различия Proc/lambda Копировать
# Обычный запуск проходит. Найдите скрытый риск.
strict = ->(x) { x * 2 }
loose = proc { |x| x.to_i * 2 }
p loose.call(3, 9)
begin
strict.call(3, 9)
rescue => e
p e.class
end
Замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод. Уязвимое место возникает потому, что lambda проверяет арность строже и `return` из неё возвращает только из lambda; обычный Proc мягче принимает аргументы, а `return` пытается покинуть окружающий метод.
Без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта. Уязвимое место возникает потому, что lambda проверяет арность строже и `return` из неё возвращает только из lambda; обычный Proc мягче принимает аргументы, а `return` пытается покинуть окружающий метод.
Если одно изменяемое состояние разделяют несколько замыканий или потоков, порядок вызовов превращается в скрытую зависимость. Уязвимое место возникает потому, что lambda проверяет арность строже и `return` из неё возвращает только из lambda; обычный Proc мягче принимает аргументы, а `return` пытается покинуть окружающий метод.
Замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод. Уязвимое место возникает потому, что блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока.
Замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод. Уязвимое место возникает потому, что блок захватывает привязки из лексического окружения, поэтому может читать и изменять внешнюю локальную переменную после создания.
Вопрос 10 из 20
На какой контракт языка или библиотеки опирается результат блока «Вызов блока через yield»? Оценивайте ответ целиком: обе части утверждения должны быть точными.
Блок захватывает привязки из лексического окружения, поэтому может читать и изменять внешнюю локальную переменную после создания. Из этого следует, что с блоком метод возвращает 12, а без блока — исходное значение 4.
`yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`. Из этого следует, что метод дважды вызывает переданный блок через `call`, поэтому результат равен 7.
`yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`. Из этого следует, что два вызова счётчика возвращают 1 и 2: замыкание хранит одну и ту же привязку `count`.
Блок не является обычным объектом-аргументом, пока его явно не захватили через `&block`; передать можно не более одного блока. Из этого следует, что с блоком метод возвращает 12, а без блока — исходное значение 4.
`yield` вызывает неявно переданный блок без создания объекта Proc; наличие блока можно проверить `block_given?`. Из этого следует, что с блоком метод возвращает 12, а без блока — исходное значение 4.
Вопрос 13 из 20
Какой рефакторинг делает контракт блока «Передача блока» явным и проверяемым? В правильном ответе вторая часть действительно объясняет или проверяет первую.
Ruby Ruby — Передача блока Копировать
# Выберите изменение, которое исправляет причину.
def twice(value, &block)
block.call(block.call(value))
end
p twice(3) { |n| n + 2 }
Инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно. Так закрывается риск: без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта.
Если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него. Так закрывается риск: без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта.
Если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него. Так закрывается риск: замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод.
Сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError. Так закрывается риск: без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта.
Если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него. Так закрывается риск: если одно изменяемое состояние разделяют несколько замыканий или потоков, порядок вызовов превращается в скрытую зависимость.
Вопрос 14 из 20
Что следует изменить в решении «Вызов блока через yield», чтобы закрыть исходный риск? Одного совпавшего вывода недостаточно — проверьте также вторую часть ответа.
Ruby Ruby — Вызов блока через yield Копировать
# Выберите изменение, которое исправляет причину.
def transform(value)
return value unless block_given?
yield(value) * 3
end
p transform(4) { |n| n }
p transform(4)
Инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно. Это изменение устраняет проблему: без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код.
Если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него. Это изменение устраняет проблему: без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код.
Сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError. Это изменение устраняет проблему: без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта.
Сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError. Это изменение устраняет проблему: замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод.
Сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError. Это изменение устраняет проблему: без ветки для отсутствующего блока `yield` поднимает LocalJumpError, что редко ожидает вызывающий код.
Вопрос 16 из 20
Какое изменение устраняет причину проблемы в теме «Замыкания», а не маскирует симптом? Оценивайте ответ целиком: обе части утверждения должны быть точными.
Инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно. Решение адресует следующий дефект: если одно изменяемое состояние разделяют несколько замыканий или потоков, порядок вызовов превращается в скрытую зависимость.
Инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно. Решение адресует следующий дефект: замена lambda на Proc ради удобства может скрыть неправильное число аргументов или преждевременно завершить внешний метод.
Сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError. Решение адресует следующий дефект: если одно изменяемое состояние разделяют несколько замыканий или потоков, порядок вызовов превращается в скрытую зависимость.
Если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него. Решение адресует следующий дефект: если одно изменяемое состояние разделяют несколько замыканий или потоков, порядок вызовов превращается в скрытую зависимость.
Инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно. Решение адресует следующий дефект: без проверки `block_given?` вызов `block.call` при отсутствии блока поднимет NoMethodError вместо понятного контракта.
Вопрос 17 из 20
Какой контрпример проверит реальную границу механизма «Передача блока»? Сопоставьте не только итог, но и правило, риск или проверку, которые с ним связаны.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Этот сценарий проверяет исправление: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Этот сценарий проверяет исправление: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Этот сценарий проверяет исправление: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.
Создать два независимых счётчика и проверить, что их состояния не смешиваются; затем проверить вызовы из разных потоков. Этот сценарий проверяет исправление: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Этот сценарий проверяет исправление: инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно.
Вопрос 18 из 20
Что нужно воспроизвести отдельно перед выпуском изменения «Вызов блока через yield»? В правильном ответе вторая часть действительно объясняет или проверяет первую.
Проверить исключение внутри блока: оно проходит через `yield`, если метод не перехватывает его явно. Так проверяется решение: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Так проверяется решение: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Так проверяется решение: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.
Проверить исключение внутри блока: оно проходит через `yield`, если метод не перехватывает его явно. Так проверяется решение: инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно.
Проверить исключение внутри блока: оно проходит через `yield`, если метод не перехватывает его явно. Так проверяется решение: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.
Вопрос 19 из 20
Какой регрессионный пример обнаружит ошибочное обобщение в теме «Различия Proc/lambda»? Сопоставьте не только итог, но и правило, риск или проверку, которые с ним связаны.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Проверка относится к изменению: выбирать lambda для передаваемой функции с контрактом, а Proc — только когда мягкая арность и нелокальный `return` действительно нужны.
Создать два независимых счётчика и проверить, что их состояния не смешиваются; затем проверить вызовы из разных потоков. Проверка относится к изменению: выбирать lambda для передаваемой функции с контрактом, а Proc — только когда мягкая арность и нелокальный `return` действительно нужны.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Проверка относится к изменению: выбирать lambda для передаваемой функции с контрактом, а Proc — только когда мягкая арность и нелокальный `return` действительно нужны.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Проверка относится к изменению: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Проверка относится к изменению: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.
Вопрос 20 из 20
Какой сценарий должен падать на старой реализации и проходить после исправления «Замыкания»? Не выбирайте ответ по одному точному фрагменту: вся формулировка должна выдерживать проверку.
Проверить блок другой арности и блок, который возвращает nil: последующий вызов может получить неожиданный тип. Сценарий подтверждает надёжность решения: инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно.
Создать два независимых счётчика и проверить, что их состояния не смешиваются; затем проверить вызовы из разных потоков. Сценарий подтверждает надёжность решения: если блок обязателен, явно поднять ArgumentError с объяснением; если необязателен — задать отдельное поведение без него.
Отдельно проверить `break` и `return` у Proc, созданного на верхнем уровне и внутри уже завершившегося метода. Сценарий подтверждает надёжность решения: инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно.
Создать два независимых счётчика и проверить, что их состояния не смешиваются; затем проверить вызовы из разных потоков. Сценарий подтверждает надёжность решения: инкапсулировать важное состояние в объект с именованными операциями и синхронизацией, если доступ возможен конкурентно.
Создать два независимых счётчика и проверить, что их состояния не смешиваются; затем проверить вызовы из разных потоков. Сценарий подтверждает надёжность решения: сформулировать, обязателен ли блок, и закрепить оба пути отдельными примерами, а не полагаться на случайный LocalJumpError.