liveBook · Manning

Defensive copy

As explained in Grokking Simplicity

A technique that copies data intended to be retained so subsequent modifications cannot alter the retained version.

A defensive copy protects immutable data when it crosses into code that may mutate it. Deep-copy data before it leaves your safe zone and again when modified data returns. section 7.3 section 7.5

Apply the discipline at both boundaries:

  • Copy as data leaves: make a deep copy, then pass the copy to untrusted code. section 7.5
  • Copy as data enters: immediately deep-copy received data and use only the copy inside your code. section 7.5
  • Use deep copies because nested structures must be duplicated from the top level to the bottom. section 7.13
  • Prefer copy-on-write inside the safe zone when you control modifications; reserve defensive copying for exchanges with untrusted code. section 7.8

Protecting a shopping cart

Before calling a mutating promotion routine, create cart_copy = deepCopy(shopping_cart). After the routine returns, assign shopping_cart = deepCopy(cart_copy). A safe wrapper can hide both copies and expose a reliable interface. section 7.4 section 7.6

function add_item_to_cart(name, price) {
    var item = make_cart_item(name, price);
    shopping_cart = add_item(shopping_cart, item);
    var total = calc_total(shopping_cart);
    set_cart_total_dom(total);
    update_shipping_icons(shopping_cart);
    update_tax_dom(total);
 
    shopping_cart =
        black_friday_promotion_safe(shopping_cart);
}
 
function black_friday_promotion_safe(cart) {
var cart_copy = deepCopy(cart);
black_friday_promotion(cart_copy);
return deepCopy(cart_copy);
} #1

Inspect a compact JavaScript wrapper that copies data before calling mutating legacy code and copies the result before returning it. section 7.6

How Grokking Simplicity covers it

How deep it goes
Defines two boundary rules, explains deep versus shallow copies, and demonstrates JavaScript wrappers without detailing deep-copy internals.
Examples
Uses a shopping cart promotion, payroll library wrapper, user-change subscription, web APIs, and Erlang or Elixir processes.
What it assumes
Assumes familiarity with immutability and copy-on-write while teaching defensive copying and deep-versus-shallow copying explicitly.
What you can do after
Apply it via deep-copy wrappers that safely exchange data with mutating functions and return protected results.
How it connects
Connects immutability with copy-on-write, deep copy, shallow copy, safe zones, and untrusted code.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Grokking Simplicity. The section links point to the parts of the book it draws on.