Class: Farce::Deduper

Inherits:
Object
  • Object
show all
Includes:
Shareable::Immutable
Defined in:
lib/farce/deduper.rb

Overview

Reuse equal frozen values throughout object graphs. Plain strings use Ruby's string deduplication. Arrays, hashes, and Ruby Sets are frozen and cached by default. Other objects are traversed but are not cached unless their class matches #store. Modules and classes are skipped by default.

Cached objects are held weakly. Keep a reference to a returned object if its identity matters. Shareable results can be reused across Ractors. Other results are cached within the current Ractor.

Cyclic containers are frozen after their references are connected and are not cached. This keeps canonical replacements from breaking back references.

Examples:

Use an independent cache

deduper = Farce::Deduper.new
first = deduper.dedup(["name"], copy: true)
deduper.dedup(["name"]).equal?(first) # => true

Instance Method Summary collapse

Methods included from Shareable

#ractor_shareable?

Instance Method Details

#dedup(object, copy: false, skip: nil) ⇒ Object

Replace equal values with cached instances, including nested keys and values. By default, mutable containers are updated and cached containers are frozen. Use copy: true to preserve the input. Skipped objects are always returned unchanged. Strings are deduplicated before skip rules are checked. Noncopyable coordination objects follow Walker.modify's in-place behavior.

Parameters:

  • object (Object) —

    the root object

  • copy (Boolean, Symbol) (defaults to: false) —

    copying policy passed to Walker.modify

  • skip (Module, Array<Module>, nil) (defaults to: nil) —

    additional exclusions for this call

Returns:

  • (Object) —

    the deduplicated result

See Also:



76
77
78
79
# File 'lib/farce/deduper.rb', line 76

def dedup(object, copy: false, skip: nil)
  skip = skip ? [*@skip, *skip] : @skip.to_a
  dedup!(object, skip, @store.to_a, copy)
end

#skip(*modules) ⇒ self

Exclude matching objects and their children from subsequent calls.

Parameters:

  • modules (Array<Module>) —

    classes or modules matched with is_a?

Returns:

  • (self)


51
52
53
54
# File 'lib/farce/deduper.rb', line 51

def skip(*modules)
  @skip.concat(modules)
  self
end

#store(*modules) ⇒ self

Also freeze and cache objects matching these classes or modules. Define consistent hash, eql?, and == methods for custom value classes. These methods must remain stable after deduplication.

Parameters:

  • modules (Array<Module>) —

    classes or modules matched with is_a?

Returns:

  • (self)


61
62
63
64
# File 'lib/farce/deduper.rb', line 61

def store(*modules)
  @store.concat(modules)
  self
end