Простіше кажучи: якщо ми вже отримали результат і він досі актуальний — навіщо виконувати дорогу операцію ще раз?
У Ruby класичний pattern виглядає так:
def permissions
@permissions ||= current_user.permissions.to_a
end
Під час першого виклику
permissions Ruby обчислить праву частину та збереже результат у @permissions.Під час наступних викликів буде використано вже збережене значення.
Тобто:
permissions → отримали дані → зберегли в @permissions → використовуємо повторно
Навіщо потрібна мемоізація?
🔘 уникати повторних дорогих обчислень;
🔘 зменшувати кількість повторних операцій із БД або API;
🔘 не виконувати одну й ту саму роботу кілька разів;
🔘 у відповідних сценаріях — покращувати performance..
Розглянемо Rails-приклад
Уявімо, що під час обробки запиту нам кілька разів потрібно отримати permissions користувача:
def permissions
current_user.permissions.to_a
end
Кожен виклик методу знову виконує його логіку.
Можемо memoize результат:
def permissions
@permissions ||= current_user.permissions.to_a
end
Тепер результат зберігається в instance variable конкретного об‘єкта й може повторно використовуватися протягом його життя.
⚠️ А тепер класична пастка Ruby.
||= працює добре, доки false або nil не є валідним результатом.Наприклад:
def active?
@active ||= expensive_check
end
Якщо
expensive_check поверне false, наступний виклик знову виконає expensive_check, адже false не є truthy значенням.У такому випадку можна перевіряти, чи instance variable вже була визначена:
def active?
return @active if defined?(@active)
@active = expensive_check
end
Тепер навіть
false або nil можуть бути коректно memoized.⚠️ Ще один важливий момент: memoization — це не те саме, що caching.
Наприклад:
@permissions
зберігається в конкретному Ruby object і живе стільки, скільки живе цей object.
Це не те саме, що
Rails.cache, і не те саме, що Active Record Query Cache, який Rails використовує для кешування результатів SQL-запитів у своєму execution context.Тому scope і lifetime memoized значення завжди мають значення.
💡 Головна ідея: якщо результат операції вже отримано, залишається актуальним і потрібен повторно — немає сенсу виконувати ту саму роботу ще раз.
Але пам‘ятайте: memoization любить актуальні дані та не любить
false, захований за ||=.TikTok | Instagram | Telegram