Class: Weak::Set

Inherits:
Object
  • Object
show all
Includes:
Enumerable, [ Weak[ Weak::Set[ Weak::Set::WeakKeysWithDelete, Weak::Set::WeakKeys, Weak::Set::StrongKeys, Weak::Set::StrongSecondaryKeys ].find(&:usable?)
Defined in:
lib/weak/set.rb,
lib/weak/set/weak_keys.rb,
lib/weak/set/strong_keys.rb,
lib/weak/set/strong_secondary_keys.rb,
lib/weak/set/weak_keys_with_delete.rb

Overview

This library provides the Weak::Set class. It behaves similar to the ::Set class of the Ruby standard library, but all values are only weakly referenced. That way, all values can be garbage collected and silently removed from the set unless they are still referenced from some other live object.

Set uses ObjectSpace::WeakMap as storage, so you must note the following points:

  • Equality of elements is determined strictly by their object identity instead of Object#eql? or Object#hash as the Set does by default.
  • Elements can be freely changed without affecting the set.
  • All elements can be freely garbage collected by Ruby. They will be removed from the set automatically.
  • The order of elements in the set is non-deterministic. Insertion order is not preserved.

Note that Set is not inherently thread-safe. When accessing a Set from multiple threads or fibers, you MUST use a mutex or another locking mechanism.

Implementation Details

The supported Ruby implementations and versions implement diverse behavior in their respective ObjectSpace::WeakMap implementations. To provide a unified behavior on all implementations, we use different storage strategies:

  • Ruby (aka. MRI, aka. YARV) >= 3.3 has an ObjectSpace::WeakMap with weak keys and weak values and the ability to delete elements from it. This allows a straight-forward implementation in WeakKeysWithDelete.
  • Ruby (aka. MRI, aka. YARV) < 3.3 has an ObjectSpace::WeakMap with weak keys and weak values but does not allow to directly delete entries. We emulate this with special garbage-collectible values in WeakKeys.
  • JRuby >= 9.4.6.0 and TruffleRuby >= 22 have an ObjectSpace::WeakMap with strong keys and weak values. To allow a entries in an ObjectSpace::WeakMap to be garbage collected, we can't use the actual object as a key. Instead, we use the element's object_id as a key. As these ObjectSpace::WeakMap objects also do not allow to delete entries, we emulate deletion with special garbage-collectible values as above. This is implemented in StrongKeys.
  • JRuby < 9.4.6.0 has a similar ObjectSpace::WeakMap as newer JRuby versions with strong keys and weak values. However generally in JRuby, Integer values (including object_ids) can have multiple different object representations in memory and are not necessarily equal to each other when used as keys in an ObjectSpace::WeakMap. As a workaround we use an indirect implementation with a secondary lookup table for the keys in StrongSecondaryKeys.

The required strategy is selected automatically based in the running Ruby. The external behavior is the same for all implementations.

Examples:

require "weak/set"

s1 = Weak::Set[1, 2]                  #=> Weak::Set[1, 2]
s2 = Weak::Set.new [1, 2]             #=> Weak::Set[1, 2]
s1 == s2                              #=> true
s1.add(:foo)                          #=> Weak::Set[1, 2, :foo]
s1.merge([2, 6])                      #=> Weak::Set[1, 2, 6, :foo]
s1.subset?(s2)                        #=> false
s2.subset?(s1)                        #=> true

Defined Under Namespace

Modules: StrongKeys, StrongSecondaryKeys, WeakKeys, WeakKeysWithDelete

Constant Summary collapse

STRATEGY =

We try to find the best implementation strategy based on the current Ruby engine and version. The chosen STRATEGY is included into the Weak::Set class.

[
  Weak::Set::WeakKeysWithDelete,
  Weak::Set::WeakKeys,
  Weak::Set::StrongKeys,
  Weak::Set::StrongSecondaryKeys
].find(&:usable?)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(enum = nil) {|element| ... } ⇒ Set

Returns a new instance of Set.

Parameters:

Yields:

  • (element)

    calls the given block once for each element in enum and add the block's return value instead if the enum's value. Make sure to only return objects which are references somewhere else to avoid them being quickly garbage collected again.

Yield Parameters:

  • element (Object)

    the yielded value from the enum



236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/weak/set.rb', line 236

def initialize(enum = nil)
  clear

  return if enum.nil?
  if block_given?
    do_with_enum(enum) do |obj|
      add yield(obj)
    end
  else
    do_with_enum(enum) do |obj|
      add obj
    end
  end
end

Class Method Details

.[](*objects) ⇒ Weak::Set

Returns a new weak set containing the given objects.

Examples:

Weak::Set[1, 2]                   # => Weak::Set[1, 2]
Weak::Set[1, 2, 1]                # => Weak::Set[1, 2]
Weak::Set[1, :c, :s]              # => Weak::Set[1, :c, :s]

Parameters:

  • objects (Array<Object>)

    a list of objects

Returns:

  • (Weak::Set)

    a new weak set containing the given objects

See Also:



226
227
228
# File 'lib/weak/set.rb', line 226

def self.[](*objects)
  new(objects)
end

Instance Method Details

#&(enum) ⇒ Weak::Set Also known as: intersection

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns a new weak set containing elements common to self and the given enumerable object.

Examples:

Weak::Set[1, 3, 5] & Weak::Set[3, 2, 1]    # => Weak::Set[1, 3]
Weak::Set[1, 2, 9] & [2, 1, 3]             # => Weak::Set[1, 2]

Parameters:

  • enum (see #do_with_enum g)

Returns:

  • (Weak::Set)

    a new weak set containing elements common to self and the given enumerable object.



296
297
298
299
300
301
302
# File 'lib/weak/set.rb', line 296

def &(enum)
  new_set = self.class.new
  do_with_enum(enum) do |obj|
    new_set.add(obj) if include?(obj)
  end
  new_set
end

#-(enum) ⇒ Weak::Set Also known as: difference

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns a new weak set built by duplicating self, removing every element that appears in the given enumerable object from that.

Examples:

Weak::Set[1, 3, 5] - Weak::Set[1, 5]        # => Weak::Set[3]
Weak::Set['a', 'b', 'z'] - ['a', 'c']       # => Weak::Set["b", "z"]

Parameters:

Returns:

  • (Weak::Set)

    a new weak set built by duplicating self, removing every element that appears in the given enumerable object from that.



283
284
285
# File 'lib/weak/set.rb', line 283

def -(enum)
  dup.subtract(enum)
end

#<=>(other) ⇒ Integer?

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns 0 if self and the given set contain the same elements, -1 / +1 if self is a proper subset / superset of the given set, or nil if they both have unique elements or set is not a Weak::Set.

Parameters:

Returns:

  • (Integer, nil)

    0 if self and the given set contain the same elements, -1 / +1 if self is a proper subset / superset of the given set, or nil if they both have unique elements or set is not a Weak::Set



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/weak/set.rb', line 311

def <=>(other)
  return unless Weak::Set === other
  return 0 if equal?(other)

  other_ary = other.to_a
  own_ary = to_a
  case own_ary.size <=> other_ary.size
  when -1
    -1 if own_ary.all?(other)
  when 1
    1 if other_ary.all?(self)
  else
    0 if own_ary.all?(other)
  end
end

#==(other) ⇒ Bool

Returns true if two weak sets are equal. The equality of each couple of elements is defined according to strict object equality so that, e.g., different strings are not equal, even if they may contain the same data.

Examples:

Weak::Set[1, 2] == Weak::Set[2, 1]         #=> true
Weak::Set[1, 3, 5] == Weak::Set[1, 5]      #=> false
Weak::Set[1, 2, 3] == [1, 3, 2]            #=> false

Parameters:

  • other (Weak::Set)

    a weak set to compare to self

Returns:

  • (Bool)

    true if the other object is a weak set containing exactly the same elements as self, false otherwise



339
340
341
342
343
344
345
346
347
348
# File 'lib/weak/set.rb', line 339

def ==(other)
  return true if equal?(other)
  return false unless Weak::Set === other

  other_ary = other.to_a
  own_ary = to_a

  return false unless own_ary.size == other_ary.size
  own_ary.all?(other)
end

#[](obj) ⇒ Object?

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns the provided obj if it is included in self, nil otherwise.

Parameters:

  • obj (Object)

    an object

Returns:

  • (Object, nil)

    the provided obj if it is included in self, nil otherwise

See Also:



376
377
378
# File 'lib/weak/set.rb', line 376

def [](obj)
  obj if include?(obj)
end

#^(enum) ⇒ Weak::Set

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns a new weak set containing elements exclusive between self and the given enumerable object. (set ^ enum) is equivalent to ((set | enum) - (set & enum)).

Examples:

Weak::Set[1, 2] ^ Set[2, 3]           #=> Weak::Set[1, 3]
Weak::Set[1, :b, :c] ^ [:b, :d]       #=> Weak::Set[1, :c, :d]

Parameters:

Returns:



361
362
363
364
365
366
367
368
369
# File 'lib/weak/set.rb', line 361

def ^(enum)
  return dup if enum.nil?

  new_set = self.class.new.merge(enum)
  each do |obj|
    new_set.add(obj) unless new_set.delete?(obj)
  end
  new_set
end

#add(obj) ⇒ self Also known as: <<

Adds the given object to the weak set and return self. Use #merge to add many elements at once.

In contrast to other "regular" objects, we will not retain a strong reference to the added object. Unless some other live objects still references the object, it will eventually be garbage-collected.

Examples:

Weak::Set[1, 2].add(3)                #=> Weak::Set[1, 2, 3]
Weak::Set[1, 2].add([3, 4])           #=> Weak::Set[1, 2, [3, 4]]
Weak::Set[1, 2].add(2)                #=> Weak::Set[1, 2]

Parameters:

  • obj (Object)

    an object

Returns:

  • (self)


# File 'lib/weak/set.rb', line 184

#add?(obj) ⇒ self?

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Adds the given object to the weak set and returns self. If the object is already in the set, returns nil.

Examples:

Weak::Set[1, 2].add?(3)              #=> Weak::Set[1, 2, 3]
Weak::Set[1, 2].add?([3, 4])         #=> Weak::Set[1, 2, [3, 4]]
Weak::Set[1, 2].add?(2)              #=> nil

Parameters:

  • obj (Object)

    an object to add to the weak set

Returns:

  • (self, nil)

    self if the object was added, nil if it was part of the set already



392
393
394
# File 'lib/weak/set.rb', line 392

def add?(obj)
  add(obj) unless include?(obj)
end

#clearself

Removes all elements and returns self

Returns:

  • (self)


# File 'lib/weak/set.rb', line 187

#clone(freeze: false) ⇒ Weak::Set

Weak::Set objects can't be frozen since this is not enforced by the underlying ObjectSpace::WeakMap implementation. Thus, we try to signal this by not actually setting the frozen? flag and ignoring attempts to freeze us with just a warning.

Parameters:

  • freeze (Bool, nil) (defaults to: false)

    ignored; we always behave as if this is false. If this is set to a truethy value, we emit a warning.

Returns:

  • (Weak::Set)

    a new Weak::Set object containing the same elements as self



405
406
407
408
409
# File 'lib/weak/set.rb', line 405

def clone(freeze: false)
  warn("Can't freeze #{self.class}") if freeze

  super(freeze: false)
end

#compare_by_identityself

This method does nothing as we always compare elements by their object identity.

Returns:

  • (self)


415
416
417
# File 'lib/weak/set.rb', line 415

def compare_by_identity
  self
end

#compare_by_identity?true

Returns always true since we always compare elements by their object identity.

Returns:

  • (true)

    always true since we always compare elements by their object identity



421
422
423
# File 'lib/weak/set.rb', line 421

def compare_by_identity?
  true
end

#delete(obj) ⇒ self

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Deletes the given object from self and returns self. Use #subtract to delete many items at once.

Parameters:

  • obj (Object)

    an object to delete from the weak set

Returns:

  • (self)

    always returns self

See Also:



432
433
434
435
# File 'lib/weak/set.rb', line 432

def delete(obj)
  delete?(obj)
  self
end

#delete?(obj) ⇒ self?

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Deletes the given object from self and returns self if the given object was present in the set. If the object was not in the set, returns nil.

Parameters:

  • obj (Object)

Returns:

  • (self, nil)

    self if the given object was present in the set and was deleted accordingly or nil if the object was not part of the set

See Also:



# File 'lib/weak/set.rb', line 190

#delete_if {|element| ... } ⇒ self, Enumerator

Deletes every element of the weak set for which the given block block evaluates to a truethy value, and returns self. Returns an Enumerator if no block is given.

Yields:

  • (element)

    calls the given block once with each element. If the block returns a truethy value, the element is deleted from the set

Yield Parameters:

  • element (Object)

    a live element of the set

Returns:

  • (self, Enumerator)

    self or an Enumerator if no block was given

See Also:



446
447
448
449
450
451
452
453
# File 'lib/weak/set.rb', line 446

def delete_if(&block)
  return enum_for(__method__) { size } unless block_given?

  each do |obj|
    delete?(obj) if yield(obj)
  end
  self
end

#disjoint?(enum) ⇒ Bool

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if self and the given enum have no element in common. This method is the opposite of #intersect?.

Returns:

  • (Bool)

    true if self and the given enum have no element in common. This method is the opposite of #intersect?.



459
460
461
# File 'lib/weak/set.rb', line 459

def disjoint?(enum)
  !intersect?(enum)
end

#each {|element| ... } ⇒ self, Enumerator

Calls the given block once for each live element in self, passing that element as a parameter. Returns the weak set itself.

If no block is given, an Enumerator is returned instead.

Yields:

  • (element)

    calls the given block once for each element in self

Yield Parameters:

  • element (Object)

    the yielded value

Returns:

  • (self, Enumerator)

    self if a block was given or an Enumerator if no block was given.



# File 'lib/weak/set.rb', line 193

#empty?Boolean

Returns true if self contains no elements.

Returns:

  • (Boolean)

    true if self contains no elements



464
465
466
# File 'lib/weak/set.rb', line 464

def empty?
  size == 0
end

#freezeself

Weak::Set objects can't be frozen since this is not enforced by the underlying ObjectSpace::WeakMap implementation. Thus, we try to signal this by not actually setting the frozen? flag and ignoring attempts to freeze us with just a warning.

Returns:

  • (self)


474
475
476
477
# File 'lib/weak/set.rb', line 474

def freeze
  warn("Can't freeze #{self.class}")
  self
end

#include?(obj) ⇒ Bool Also known as: ===, member?

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if the given object is included in self, false otherwise.

Parameters:

  • obj (Object)

    an object

Returns:

  • (Bool)

    true if the given object is included in self, false otherwise



# File 'lib/weak/set.rb', line 196

#inspectString Also known as: to_s

Note:

The elements of the set are ordered by their object id in the inspect output. If we detect a reference cycle (e.g. with a set containing itself), we output "Weak::Set[...]".

Returns a string containing a human-readable representation of the weak set, e.g., "Weak::Set[element1, element2, ...]".

Returns:

  • (String)

    a string containing a human-readable representation of the weak set, e.g., "Weak::Set[element1, element2, ...]"



484
485
486
487
488
489
490
491
492
493
494
495
# File 'lib/weak/set.rb', line 484

def inspect
  object_ids = (Thread.current[INSPECT_KEY] ||= [])
  return "#{self.class}[...]" if object_ids.include?(object_id)

  object_ids << object_id
  begin
    elements = to_a.sort_by!(&:__id__).inspect[1..-2]
    "#{self.class}[#{elements}]"
  ensure
    object_ids.pop
  end
end

#intersect?(enum) ⇒ Bool

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if self and the given enumerable object have at least one element in common, false otherwise.

Examples:

Weak::Set[1, 2, 3].intersect? Weak::Set[4, 5]   #=> false
Weak::Set[1, 2, 3].intersect? Weak::Set[3, 4]   #=> true
Weak::Set[1, 2, 3].intersect? 4..5              #=> false
Weak::Set[1, 2, 3].intersect? [3, 4]            #=> true

Parameters:

  • enum (Weak::Set, Enumerable, #each_entry, #each)

    a Weak::Set, or an Enumerable object, e.g. an Array or Set, or an object which responds to each_entry or each

Returns:

  • (Bool)

    true if self and the given enumerable object have at least one element in common, false otherwise



508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/weak/set.rb', line 508

def intersect?(enum)
  case enum
  when Weak::Set
    enum_ary = enum.to_a
    own_ary = to_a

    if own_ary.size < enum_ary.size
      own_ary.any?(enum)
    else
      enum_ary.any?(self)
    end
  else
    enumerable(enum).any?(self)
  end
end

#keep_if {|element| ... } ⇒ Enumerator, self

Deletes every element from self for which the given block evaluates to a falsey value.

If no block is given, an Enumerator is returned instead.

Yields:

  • (element)

    calls the given block once for each element in the array

Yield Parameters:

  • element (Object)

    the element to check

Returns:

  • (Enumerator, self)

    self if a block was given, or an Enumerator if no block was given.

See Also:



535
536
537
538
539
540
541
542
# File 'lib/weak/set.rb', line 535

def keep_if(&block)
  return enum_for(__method__) { size } unless block_given?

  each do |obj|
    delete?(obj) unless yield(obj)
  end
  self
end

#merge(*enums) ⇒ self

Merges the elements of the given enumerable objects to the set and returns self

Parameters:

  • enums (Array<#each_entry, #each>)

    a list of enumerable objects

Returns:

  • (self)


549
550
551
552
553
554
555
556
# File 'lib/weak/set.rb', line 549

def merge(*enums, **nil)
  enums.each do |enum|
    do_with_enum(enum) do |obj|
      add(obj)
    end
  end
  self
end

#proper_subset?(other) ⇒ Bool Also known as: <

Returns true if self is a proper subset of the given set, false otherwise.

Parameters:

Returns:

  • (Bool)

    true if self is a proper subset of the given set, false otherwise

See Also:



576
577
578
579
580
581
582
583
584
585
586
# File 'lib/weak/set.rb', line 576

def proper_subset?(other)
  if Weak::Set === other
    other_ary = other.to_a
    own_ary = to_a

    return false unless own_ary.size < other_ary.size
    own_ary.all?(other)
  else
    raise ArgumentError, "value must be a weak set"
  end
end

#proper_superset?(other) ⇒ Bool Also known as: >

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if self is a proper superset of the given set, false otherwise.

Parameters:

Returns:

  • (Bool)

    true if self is a proper superset of the given set, false otherwise

See Also:



594
595
596
597
598
599
600
601
602
603
604
# File 'lib/weak/set.rb', line 594

def proper_superset?(other)
  if Weak::Set === other
    other_ary = other.to_a
    own_ary = to_a

    return false unless own_ary.size > other_ary.size
    other_ary.all?(self)
  else
    raise ArgumentError, "value must be a weak set"
  end
end

#pruneself Also known as: reset

Cleanup data structures from the set to remove data associated with deleted or garbage collected elements. This method may be called automatically for some Weak::Set operations.

Returns:

  • (self)


# File 'lib/weak/set.rb', line 199

#reject! {|element| ... } ⇒ Enumerator, ...

Deletes every live element from self for which the given block evaluates to a truethy value.

Equivalent to #delete_if, but returns nil if no changes were made.

If no block is given, an Enumerator is returned instead.

Yields:

  • (element)

    calls the given block once for each live object in self

Yield Parameters:

  • element (Object)

    the element to check

Returns:

  • (Enumerator, self, nil)

    self if a block was given and some element(s) were deleted, nil if a block was given but no keys were deleted, or an Enumerator if no block was given.

See Also:



620
621
622
623
624
625
626
627
628
629
# File 'lib/weak/set.rb', line 620

def reject!(&block)
  return enum_for(__method__) { size } unless block_given?

  deleted_anything = false
  each do |obj|
    deleted_anything = true if yield(obj) && delete?(obj)
  end

  self if deleted_anything
end

#replace(enum) ⇒ self

Replaces the contents of self with the contents of the given enumerable object and returns self.

Examples:

set = Weak::Set[1, :c, :s]        #=> Weak::Set[1, :c, :s]
set.replace([1, 2])               #=> Weak::Set[1, 2]
set                               #=> Weak::Set[1, 2]

Returns:

  • (self)


# File 'lib/weak/set.rb', line 205

#select! {|element| ... } ⇒ Enumerator, ... Also known as: filter!

Deletes every element from self for which the given block evaluates to a falsey value.

Equivalent to #keep_if, but returns nil if no changes were made.

If no block is given, an Enumerator is returned instead.

Yields:

  • (element)

    calls the given block once for each element in the set

Yield Parameters:

  • element (Object)

    the element to check

Returns:

  • (Enumerator, self, nil)

    self if a block was given and some element(s) were deleted, nil if a block was given but nothing was deleted, or an Enumerator if no block was given.

See Also:



644
645
646
647
648
649
650
651
652
653
# File 'lib/weak/set.rb', line 644

def select!(&block)
  return enum_for(__method__) { size } unless block_given?

  deleted_anything = false
  each do |obj|
    deleted_anything = true if !yield(obj) && delete?(obj)
  end

  self if deleted_anything
end

#sizeInteger Also known as: length

Returns the number of live elements in self.

Returns:

  • (Integer)

    the number of live elements in self



# File 'lib/weak/set.rb', line 202

#subset?(other) ⇒ Bool Also known as: <=

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if self is a subset of the given set, false otherwise.

Parameters:

Returns:

  • (Bool)

    true if self is a subset of the given set, false otherwise

See Also:



661
662
663
664
665
666
667
668
669
670
671
# File 'lib/weak/set.rb', line 661

def subset?(other)
  if Weak::Set === other
    other_ary = other.to_a
    own_ary = to_a

    return false unless own_ary.size <= other_ary.size
    own_ary.all?(other)
  else
    raise ArgumentError, "value must be a weak set"
  end
end

#subtract(enum) ⇒ self

Deletes every element from self which appears in the given enumerable object enum and returns self.

Parameters:

Returns:

  • (self)


679
680
681
682
683
684
# File 'lib/weak/set.rb', line 679

def subtract(enum)
  do_with_enum(enum) do |obj|
    delete?(obj)
  end
  self
end

#superset?(other) ⇒ Bool Also known as: >=

Returns true if self is a superset of the given set, false otherwise.

Parameters:

Returns:

  • (Bool)

    true if self is a superset of the given set, false otherwise

See Also:



690
691
692
693
694
695
696
697
698
699
700
# File 'lib/weak/set.rb', line 690

def superset?(other)
  if Weak::Set === other
    other_ary = other.to_a
    own_ary = to_a

    return false unless own_ary.size >= other_ary.size
    other_ary.all?(self)
  else
    raise ArgumentError, "value must be a weak set"
  end
end

#to_aArray

Note:

The order of elements on the returned Array is non-deterministic. We do not preserve preserve insertion order.

Returns the live elements contained in self as an Array.

Returns:

  • (Array)

    the live elements contained in self as an Array



# File 'lib/weak/set.rb', line 208

#to_setSet

Note:

The returned set is configured to compare elements by their object identity, similar to a Weak::Set.

Returns the elements in self as a regular Set with strong object references.

Returns:

  • (Set)

    the elements in self as a regular Set with strong object references



707
708
709
710
711
712
713
# File 'lib/weak/set.rb', line 707

def to_set
  set = ::Set.new.compare_by_identity
  each do |obj|
    set.add(obj)
  end
  set
end

#|(enum) ⇒ Weak::Set Also known as: +, union

Note:

Weak::Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns a new weak set built by merging self and the elements of the given enumerable object.

Examples:

Weak::Set[1, 2, 3] | Weak::Set[2, 4, 5] # => Weak::Set[1, 2, 3, 4, 5]
Weak::Set[1, 3, :z] | (1..4)            # => Weak::Set[1, 2, 3, 4, :z]

Parameters:

Returns:

  • (Weak::Set)

    a new weak set built by merging self and the elements of the given enumerable object.



265
266
267
268
269
270
271
# File 'lib/weak/set.rb', line 265

def |(enum)
  new_set = dup
  do_with_enum(enum) do |obj|
    new_set.add(obj)
  end
  new_set
end