class Zanzou::ShadowNode

Constants

IMMUTABLE_CLASSES

Public Class Methods

create(orig_obj, parent:, parent_key:) click to toggle source
# File lib/zanzou.rb, line 10
def self.create(orig_obj, parent:, parent_key:)
  case orig_obj
  when Array
    ArrayShadow.new(orig_obj, parent: parent, parent_key: parent_key)
  when Hash
    HashShadow.new(orig_obj, parent: parent, parent_key: parent_key)
  else
    if orig_obj.frozen? || IMMUTABLE_CLASSES.include?(orig_obj.class)
      orig_obj
    elsif orig_obj.respond_to?(:zanzou_class)
      orig_obj.zanzou_class.new(orig_obj, parent: parent, parent_key: parent_key)
    else
      AnyObjectShadow.new(orig_obj, parent: parent, parent_key: parent_key)
    end
  end
end
finalize(shadow) click to toggle source
# File lib/zanzou.rb, line 27
def self.finalize(shadow)
  orig_obj      = shadow.instance_variable_get(:@orig_obj)
  modified      = shadow.instance_variable_get(:@modified)
  new_obj       = shadow.instance_variable_get(:@new_obj)
  modifications = shadow.instance_variable_get(:@modifications)
  modifications.transform_values!{|v|
    ShadowNode === v ? ShadowNode.finalize(v) : v
  }

  #pp cls: shadow.class.name, orig_obj: orig_obj, modified: modified, modifications: modifications, new_obj: new_obj
  if modified
    if new_obj
      if modifications.empty?
        ret = new_obj
      else
        ret = shadow.class.merge(new_obj, modifications)
      end
    else
      if modifications.empty?
        ret = orig_obj
      else
        ret = shadow.class.merge(orig_obj, modifications)
      end
    end
  else
    ret = orig_obj
  end
  #pp ret: ret
  return ret
end
new(orig_obj, parent:, parent_key:) click to toggle source
# File lib/zanzou.rb, line 58
def initialize(orig_obj, parent:, parent_key:)
  @orig_obj, @parent, @parent_key = orig_obj, parent, parent_key
  @modified = false
  @modifications = {}
  @new_obj = nil
end

Private Instance Methods

handle_destructive_method_call(name, args) click to toggle source
# File lib/zanzou.rb, line 67
def handle_destructive_method_call(name, args)
  modified!
  @new_obj = @orig_obj.dup
  return @new_obj.public_send(name, *args)
end
handle_non_destructive_method_call(name, args) click to toggle source
# File lib/zanzou.rb, line 73
def handle_non_destructive_method_call(name, args)
  return (@new_obj || @orig_obj).public_send(name, *args)
end
modified!() click to toggle source
# File lib/zanzou.rb, line 77
def modified!
  @modified = true

  # Mark ancestors to be modified
  parent = @parent
  while parent && !parent.instance_variable_get(:@modified)
    parent.instance_variable_set(:@modified, true)
    parent = parent.instance_variable_get(:@parent)
  end

  # Tell parent for the modification
  if @parent
    @parent.instance_variable_get(:@modifications)[@parent_key] = self
  end
end