Module: Uniword::LazyLoader

Included in:
Image
Defined in:
lib/uniword/lazy_loader.rb

Overview

Module for lazy loading attributes to reduce memory footprint.

Lazy loading delays the loading of data until it is actually needed, which helps reduce memory usage for large documents.

All cached values are stored in a single Hash (@_lazy_cache) accessed via direct ivar reference — no instance_variable_get/set, no public_send, no remove_instance_variable.

Examples:

Using lazy attributes

class Document
  extend LazyLoader

  lazy_attr :paragraphs do
    parse_paragraphs_from_xml
  end
end

Instance Method Summary collapse

Instance Method Details

#lazy_attr(name, &loader) ⇒ Object

Raises:

  • (ArgumentError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/uniword/lazy_loader.rb', line 22

def lazy_attr(name, &loader)
  raise ArgumentError, "Block required for lazy_attr" unless loader

  cache_key = name

  define_method(name) do
    @_lazy_cache ||= {}
    return @_lazy_cache[cache_key] if @_lazy_cache.key?(cache_key)

    @_lazy_cache[cache_key] = instance_exec(&loader)
  end

  define_method("#{name}_loaded?") do
    @_lazy_cache ||= {}
    @_lazy_cache.key?(cache_key)
  end

  define_method("clear_#{name}") do
    @_lazy_cache ||= {}
    @_lazy_cache.delete(cache_key)
  end
end

#lazy_collection(name, &loader) ⇒ Object

Raises:

  • (ArgumentError)


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/uniword/lazy_loader.rb', line 45

def lazy_collection(name, &loader)
  raise ArgumentError, "Block required for lazy_collection" unless loader

  cache_key = name
  normalizer = method(:normalize_collection)

  define_method(name) do
    @_lazy_cache ||= {}
    return @_lazy_cache[cache_key] if @_lazy_cache.key?(cache_key)

    collection = normalizer.call(instance_exec(&loader))
    @_lazy_cache[cache_key] = collection
    collection
  end

  define_method("#{name}_loaded?") do
    @_lazy_cache ||= {}
    @_lazy_cache.key?(cache_key)
  end

  define_method("clear_#{name}") do
    @_lazy_cache ||= {}
    @_lazy_cache.delete(cache_key)
  end

  define_method("#{name}_count") do
    @_lazy_cache ||= {}
    unless @_lazy_cache.key?(cache_key)
      @_lazy_cache[cache_key] = normalizer.call(instance_exec(&loader))
    end
    @_lazy_cache[cache_key].size
  end
end