class Sequence::WeakRefSet
Public Class Methods
# File lib/sequence/weakrefset.rb, line 29 def [] *items new(items) end
create a new WeakRefSet
from an optional Enumerable
(of objects) which is optionally processed through a block
# File lib/sequence/weakrefset.rb, line 21 def initialize(items=nil,&block) # :yield: obj items=[] if items.nil? raise ArgumentError unless items.respond_to? :each items=items.map(&block) if block replace(items) end
Public Instance Methods
# File lib/sequence/weakrefset.rb, line 109 def == other return true if self.equal? other other.is_a? Set and other.size==self.size and all?{|x| other.include?(x) } end
Returns a new set containing elements exclusive between the set and the given enumerable object. (set ^ enum) is equivalent to ((set | enum) - (set & enum)).
# File lib/sequence/weakrefset.rb, line 229 def ^(enum) enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" n = self.class.new(enum) each { |o| if n.include?(o) then n.delete(o) else n.add(o) end } n end
add a weak reference to the set
# File lib/sequence/weakrefset.rb, line 67 def add(obj) # return self if include? obj # Symbol===obj || Fixnum===obj || nil==obj || true==obj || false==obj and # raise ArgumentError, "no immediates in weakrefset" id=ref obj case (o2=unref id) #test id for validity when Fixnum; obj.equal? o2 or raise when Symbol,true,false,nil; id=obj #hopefully rare else obj.equal? o2 or raise ObjectSpace.define_finalizer(obj,method(:finalizer)) end @ids[id] = true self end
clear the set (return self)
# File lib/sequence/weakrefset.rb, line 131 def clear @ids = {} self end
delete an object in the set (return self)
# File lib/sequence/weakrefset.rb, line 150 def delete(obj) delete?(obj) self end
delete an object in the set (return self if obj was found, else nil if nothing deleted)
# File lib/sequence/weakrefset.rb, line 156 def delete?(obj) x=include?(obj) if x fail unless @ids.delete(ref( obj ))||@ids.delete(obj) return self end end
Deletes every element of the set for which block evaluates to true, and returns self.
# File lib/sequence/weakrefset.rb, line 166 def delete_if to_a.each { |o| delete(o) if yield(o) } self end
iterate over remaining valid objects in the set
# File lib/sequence/weakrefset.rb, line 86 def each @ids.each_key { |id| case id when Integer @ids.include?(id) or next o = unref(id) or next #i don't know where the random symbols come from, but at least they're always symbols... else o=id end # case o # when Symbol,Fixnum,true,false,nil: warn "immediate value #{o.inspect} found in weakrefset" # else yield(o) # end } self end
any objects in the set still valid?
# File lib/sequence/weakrefset.rb, line 237 def empty? @ids.empty? end
# File lib/sequence/weakrefset.rb, line 116 def hash hashing=Thread.current[:$WeakRefSet_hashing]||=[] return 0 if hashing.include? self hashing<<self result=0 each{|x| result^=x.hash } result ensure hashing.delete(self) Thread.current[:$WeakRefSet_hashing]=nil if hashing.empty? end
is this object in the set?
# File lib/sequence/weakrefset.rb, line 172 def include?(obj) any?{|x| obj==x} end
return a human-readable string showing the set
# File lib/sequence/weakrefset.rb, line 179 def inspect #unless $weakrefset_verbose_inspect # return sprintf('#<%s:0x%x {...}>', self.class.name, object_id) #end ids = (Thread.current[:__weakrefset__inspect_key__] ||= []) if ids.include?(object_id) return sprintf('#<%s: {...}>', self.class.name) end begin ids << object_id return sprintf('#<%s: {%s}>', self.class.name, to_a.inspect[1..-2]) ensure ids.pop Thread.current[:__weakrefset__inspect_key__].empty? and Thread.current[:__weakrefset__inspect_key__]=nil end end
# File lib/sequence/weakrefset.rb, line 205 def is_complex_yaml?; true end
merge some more objects into the set (return self)
# File lib/sequence/weakrefset.rb, line 137 def merge(enum) enum.each { |obj| add(obj) } self end
replace the objects in the set (return self)
# File lib/sequence/weakrefset.rb, line 143 def replace(enum) clear merge(enum) self end
number of objects in the set still valid
# File lib/sequence/weakrefset.rb, line 242 def size @ids.size end
remove some objects from the set (return self)
# File lib/sequence/weakrefset.rb, line 221 def subtract(enum) enum.each { |obj| delete(obj) } self end
# File lib/sequence/weakrefset.rb, line 105 def to_a map{|x| x} end
# File lib/sequence/weakrefset.rb, line 211 def to_yaml( opts = {} ) YAML::quick_emit( object_id, opts ) { |out| out.map( to_yaml_type ) { |map| map.add( "items", to_yaml_properties) } } end
# File lib/sequence/weakrefset.rb, line 207 def to_yaml_type; "!inforadical.net,2005/object:WeakRefSet" end
Private Instance Methods
# File lib/sequence/weakrefset.rb, line 35 def finalizer(id) @ids.delete(id) end
# File lib/sequence/weakrefset.rb, line 43 def ref o WeakRef.create_weakref o end
# File lib/sequence/weakrefset.rb, line 46 def unref id id.at(0) rescue Exception return nil end