Class: Psych::Pure::LoadedHash

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/psych/pure.rb

Overview

Wraps a Ruby hash with its node from the source input.

Defined Under Namespace

Classes: PsychKey

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, psych_node) ⇒ LoadedHash

Returns a new instance of LoadedHash.



416
417
418
419
420
# File 'lib/psych/pure.rb', line 416

def initialize(object, psych_node)
  super(object)
  @psych_node = psych_node
  @psych_keys = []
end

Instance Attribute Details

#psych_keysObject (readonly)

The list of key/value pairs within the hash.



414
415
416
# File 'lib/psych/pure.rb', line 414

def psych_keys
  @psych_keys
end

#psych_nodeObject (readonly)

The node associated with the hash.



411
412
413
# File 'lib/psych/pure.rb', line 411

def psych_node
  @psych_node
end

Instance Method Details

#[]=(key, value) ⇒ Object Also known as: store



450
451
452
453
454
455
456
457
458
459
460
# File 'lib/psych/pure.rb', line 450

def []=(key, value)
  super(key, value)

  if (psych_key = @psych_keys.reverse_each.find { |psych_key| psych_compare?(psych_key.key_node, key) })
    psych_key.replace_value(value)
  else
    @psych_keys << PsychKey.new(key, value)
  end

  value
end

#clearObject



464
465
466
467
468
469
# File 'lib/psych/pure.rb', line 464

def clear
  super
  @psych_keys.clear

  self
end

#compactObject



483
484
485
# File 'lib/psych/pure.rb', line 483

def compact
  dup.compact!
end

#compact!Object



471
472
473
474
475
476
477
478
479
480
481
# File 'lib/psych/pure.rb', line 471

def compact!
  mutated = false
  @psych_keys.each do |psych_key|
    if psych_unwrap(psych_key.value_node).nil?
      mutated = true
      delete(psych_unwrap(psych_key.key_node))
    end
  end

  self if mutated
end

#delete(key) ⇒ Object



487
488
489
490
491
492
# File 'lib/psych/pure.rb', line 487

def delete(key)
  result = super
  psych_delete(key)

  result
end

#delete_if(&block) ⇒ Object



494
495
496
497
498
499
500
501
502
# File 'lib/psych/pure.rb', line 494

def delete_if(&block)
  super do |key, value|
    yield(key, psych_unwrap(value)).tap do |result|
      psych_delete(key) if result
    end
  end

  self
end

#except(*keys) ⇒ Object



504
505
506
# File 'lib/psych/pure.rb', line 504

def except(*keys)
  dup.delete_if { |key, _| keys.include?(key) }
end

#filter(&block) ⇒ Object



522
523
524
# File 'lib/psych/pure.rb', line 522

def filter(&block)
  dup.filter!(&block)
end

#filter!(&block) ⇒ Object



508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'lib/psych/pure.rb', line 508

def filter!(&block)
  mutated = false
  super do |key, value|
    yield(key, psych_unwrap(value)).tap do |result|
      unless result
        psych_delete(key)
        mutated = true
      end
    end
  end

  self if mutated
end

#initialize_clone(obj, freeze: nil) ⇒ Object

Override Hash mutation methods to keep @psych_keys in sync.



438
439
440
441
442
# File 'lib/psych/pure.rb', line 438

def initialize_clone(obj, freeze: nil)
  super
  @psych_node = obj.psych_node.dup
  @psych_keys = obj.psych_keys.map(&:dup)
end

#initialize_dup(obj) ⇒ Object



444
445
446
447
448
# File 'lib/psych/pure.rb', line 444

def initialize_dup(obj)
  super
  @psych_node = obj.psych_node.dup
  @psych_keys = obj.psych_keys.map(&:dup)
end

#invertObject



526
527
528
529
530
# File 'lib/psych/pure.rb', line 526

def invert
  result = LoadedHash.new({}, @psych_node)
  each { |key, value| result[psych_unwrap(value)] = key }
  result
end

#join!(key_node, value_node) ⇒ Object



427
428
429
430
# File 'lib/psych/pure.rb', line 427

def join!(key_node, value_node)
  @psych_keys << PsychKey.new(key_node, value_node)
  merge!(value_node)
end

#keep_if(&block) ⇒ Object Also known as: select!



532
533
534
535
536
537
538
539
540
# File 'lib/psych/pure.rb', line 532

def keep_if(&block)
  super do |key, value|
    yield(key, psych_unwrap(value)).tap do |result|
      psych_delete(key) unless result
    end
  end

  self
end

#merge(*others) ⇒ Object



572
573
574
# File 'lib/psych/pure.rb', line 572

def merge(*others)
  dup.merge!(*others)
end

#merge!(*others) ⇒ Object Also known as: update



544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/psych/pure.rb', line 544

def merge!(*others)
  super
  others.each do |other|
    if other.is_a?(LoadedHash)
      # When merging another LoadedHash, preserve its psych_keys to keep comments
      other.psych_keys.each do |psych_key|
        psych_delete(psych_unwrap(psych_key.key_node))
        @psych_keys << psych_key.dup
      end

      # Merge comments from the other hash's psych_node
      if other.psych_node&.comments?
        @psych_node.comments.merge(other.psych_node.comments)
      end
    else
      # Regular hash - just wrap keys and values
      other.each do |key, value|
        psych_delete(key)
        @psych_keys << PsychKey.new(key, value)
      end
    end
  end

  self
end

#psych_assocsObject



432
433
434
# File 'lib/psych/pure.rb', line 432

def psych_assocs
  @psych_keys.map { |psych_key| [psych_key.key_node, psych_key.value_node] }
end

#reject(&block) ⇒ Object



590
591
592
# File 'lib/psych/pure.rb', line 590

def reject(&block)
  dup.reject!(&block)
end

#reject!(&block) ⇒ Object



576
577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/psych/pure.rb', line 576

def reject!(&block)
  mutated = false
  super do |key, value|
    yield(key, psych_unwrap(value)).tap do |result|
      if result
        psych_delete(key)
        mutated = true
      end
    end
  end

  self if mutated
end

#replace(other) ⇒ Object



594
595
596
597
598
599
600
601
# File 'lib/psych/pure.rb', line 594

def replace(other)
  super

  @psych_keys.clear
  other.each { |key, value| @psych_keys << PsychKey.new(key, value) }

  self
end

#set!(key_node, value_node) ⇒ Object



422
423
424
425
# File 'lib/psych/pure.rb', line 422

def set!(key_node, value_node)
  @psych_keys << PsychKey.new(key_node, value_node)
  __getobj__[key_node.__getobj__] = value_node
end

#shiftObject



603
604
605
606
607
608
609
610
# File 'lib/psych/pure.rb', line 603

def shift
  unless empty?
    key, value = super
    psych_delete(key)

    [key, value]
  end
end

#slice(*keys) ⇒ Object



612
613
614
# File 'lib/psych/pure.rb', line 612

def slice(*keys)
  dup.select! { |key, _| keys.include?(key) }
end

#transform_keys(&block) ⇒ Object



629
630
631
# File 'lib/psych/pure.rb', line 629

def transform_keys(&block)
  dup.transform_keys!(&block)
end

#transform_keys!(&block) ⇒ Object



616
617
618
619
620
621
622
623
624
625
626
627
# File 'lib/psych/pure.rb', line 616

def transform_keys!(&block)
  super do |key|
    yield(key).tap do |result|
      @psych_keys
        .reverse_each
        .find { |psych_key| psych_compare?(psych_key.key_node, key) }
        &.replace_key(result)
    end
  end

  self
end

#transform_values(&block) ⇒ Object



644
645
646
# File 'lib/psych/pure.rb', line 644

def transform_values(&block)
  dup.transform_values!(&block)
end

#transform_values!(&block) ⇒ Object



633
634
635
636
637
638
639
640
641
642
# File 'lib/psych/pure.rb', line 633

def transform_values!(&block)
  super do |value|
    yield(psych_unwrap(value)).tap do |result|
      @psych_keys
        .reverse_each
        .find { |psych_key| psych_compare?(psych_key.value_node, value) }
        &.replace_value(result)
    end
  end
end