Module: Leto
- Defined in:
- lib/leto/path.rb,
lib/leto/dig.rb,
lib/leto/call.rb,
lib/leto/utils.rb,
lib/leto/version.rb
Overview
Light wrapper around Array, mostly for nicer display.
Defined Under Namespace
Classes: Path
Constant Summary collapse
- IMMUTABLE_CLASSES =
[ FalseClass, Float, if defined?(Integer) Integer else Fixnum # rubocop:disable Lint/UnifiedInteger for Ruby < 2.4 end, NilClass, Symbol, TrueClass, ].freeze
- NON_DUPLICABLE_CLASSES =
[ Method, Singleton, UnboundMethod ].freeze
- VERSION =
"2.1.0"
Class Method Summary collapse
- .call(obj, max_depth: nil, path: nil, &block) ⇒ Object
- .deep_dup(obj, include_modules: false) ⇒ Object
- .deep_eql?(obj1, obj2) ⇒ Boolean
- .deep_freeze(obj, include_modules: false) ⇒ Object
- .deep_print(obj, print_method: :inspect, indent: 4, show_path: true) ⇒ Object
- .dig(obj, steps) ⇒ Object
- .each_shared_object(obj1, obj2, filter: nil) ⇒ Object
- .shared_mutable_state?(obj1, obj2) ⇒ Boolean
-
.shared_mutables(obj1, obj2) ⇒ Object
returns [[shared_object, path1, path2], …], e.g.: str1 = ‘foo’.dup str2 = ‘bar’.dup shared_mutables([str1, str2], [str2, str1]) # => [ [“foo”, [[:[], 0]], [[:[], 1]]], [“bar”, [[:[], 1]], [[:[], 0]]] ].
- .shared_objects(obj1, obj2, filter: nil) ⇒ Object
- .trace(obj, max_depth: nil, path: nil, &block) ⇒ Object
Class Method Details
.call(obj, max_depth: nil, path: nil, &block) ⇒ Object
2 3 4 5 6 7 |
# File 'lib/leto/call.rb', line 2 def self.call(obj, max_depth: nil, path: nil, &block) block_given? or return enum_for(__method__, obj, max_depth: max_depth, path: path) traverse(obj, path, 0, max_depth, build_seen_hash, block) obj end |
.deep_dup(obj, include_modules: false) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/leto/utils.rb', line 23 def self.deep_dup(obj, include_modules: false) return obj if IMMUTABLE_CLASSES.include?(obj.class) || !duplicable?(obj) || (!include_modules && obj.is_a?(Module)) copy = obj.dup trace(obj, max_depth: 1).each do |el, path| method, *args = path.steps[0] case method when :instance_variable_get copy.instance_variable_set(*args, deep_dup(el, include_modules: include_modules)) when :[] copy[*args] = deep_dup(el, include_modules: include_modules) when :send # Data copy = copy.with(args[0] => deep_dup(el, include_modules: include_modules)) when :begin return Range.new(deep_dup(obj.begin), deep_dup(obj.end), obj.exclude_end?) end end copy end |
.deep_eql?(obj1, obj2) ⇒ Boolean
19 20 21 |
# File 'lib/leto/utils.rb', line 19 def self.deep_eql?(obj1, obj2) call(obj1).to_a == call(obj2).to_a end |
.deep_freeze(obj, include_modules: false) ⇒ Object
2 3 4 5 6 7 8 |
# File 'lib/leto/utils.rb', line 2 def self.deep_freeze(obj, include_modules: false) call(obj) do |el| el.freeze if el.respond_to?(:freeze) && !el.frozen? && (include_modules || !el.is_a?(Module)) end end |
.deep_print(obj, print_method: :inspect, indent: 4, show_path: true) ⇒ Object
10 11 12 13 14 15 16 17 |
# File 'lib/leto/utils.rb', line 10 def self.deep_print(obj, print_method: :inspect, indent: 4, show_path: true) trace(obj) do |el, path| puts "#{' ' * path.count * indent}#{el.send(print_method)}" \ "#{" @ #{path.inspect}" if show_path}" \ [0..78] end nil end |
.dig(obj, steps) ⇒ Object
2 3 4 |
# File 'lib/leto/dig.rb', line 2 def self.dig(obj, steps) Leto::Path.new(start: obj, steps: steps).resolve end |
.each_shared_object(obj1, obj2, filter: nil) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/leto/utils.rb', line 66 def self.each_shared_object(obj1, obj2, filter: nil) block_given? or return enum_for(__method__, obj1, obj2, filter: filter) obj2_els_with_path = trace(obj2).to_a trace(obj1).each do |el1, path1| next if filter && !filter.call(el1) obj2_els_with_path.reject do |el2, path2| yield(el1, path1, path2) if el1.equal?(el2) end end end |
.shared_mutable_state?(obj1, obj2) ⇒ Boolean
46 47 48 |
# File 'lib/leto/utils.rb', line 46 def self.shared_mutable_state?(obj1, obj2) each_shared_object(obj1, obj2, filter: method(:mutable?)).any? end |
.shared_mutables(obj1, obj2) ⇒ Object
returns [[shared_object, path1, path2], …], e.g.: str1 = ‘foo’.dup str2 = ‘bar’.dup shared_mutables([str1, str2], [str2, str1]) # => [
["foo", [[:[], 0]], [[:[], 1]]],
["bar", [[:[], 1]], [[:[], 0]]]
]
58 59 60 |
# File 'lib/leto/utils.rb', line 58 def self.shared_mutables(obj1, obj2) each_shared_object(obj1, obj2, filter: method(:mutable?)).to_a end |
.shared_objects(obj1, obj2, filter: nil) ⇒ Object
62 63 64 |
# File 'lib/leto/utils.rb', line 62 def self.shared_objects(obj1, obj2, filter: nil) each_shared_object(obj1, obj2, filter: filter).to_a end |
.trace(obj, max_depth: nil, path: nil, &block) ⇒ Object
9 10 11 12 13 |
# File 'lib/leto/call.rb', line 9 def self.trace(obj, max_depth: nil, path: nil, &block) block_given? or return enum_for(__method__, obj, max_depth: max_depth, path: path) call(obj, max_depth: max_depth, path: path || Path.new(start: obj), &block) end |