Class: Contrast::Utils::ClassUtil
- Defined in:
- lib/contrast/utils/class_util.rb
Overview
Utility methods for exploring the complete space of Objects
Class Method Summary collapse
- .convert_object(object) ⇒ Object
-
.prepended?(mod, ancestors = nil) ⇒ Boolean
some classes have had things prepended to them, like Marshal in Rails 5 and higher.
-
.prepended_method?(mod, method_policy) ⇒ Boolean
return true if the given method is overwritten by one of the ancestors in the ancestor change that comes before the given module.
-
.to_contrast_string(object) ⇒ String, Object
Return a String representing the object invoking this method in the form expected by our dataflow events.
-
.truly_defined?(name) ⇒ Boolean
The method Module.const_defined? can raise an exception if the constant is poorly named.
Class Method Details
.convert_object(object) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/contrast/utils/class_util.rb', line 73 def convert_object object if object.nil? Contrast::Utils::ObjectShare::NIL_STRING elsif object.cs__is_a?(Symbol) ":#{ object }" elsif object.cs__is_a?(Module) || object.cs__is_a?(Class) "#{ object.cs__name }@#{ object.__id__ }" elsif object.cs__is_a?(Regexp) object.source elsif use_to_s?(object) object.to_s else "#{ object.cs__class.cs__name }@#{ object.__id__ }" end end |
.prepended?(mod, ancestors = nil) ⇒ Boolean
some classes have had things prepended to them, like Marshal in Rails 5 and higher. Their ActiveSupport::MarshalWithAutoloading will break our alias patching approach, as will any other prepend on something that we touch. Prepend and Alias are inherently incompatible monkey patching approaches. As such, we need to know if something has been prepended to.
23 24 25 26 |
# File 'lib/contrast/utils/class_util.rb', line 23 def prepended? mod, ancestors = nil ancestors ||= mod.ancestors ancestors[0] != mod end |
.prepended_method?(mod, method_policy) ⇒ Boolean
return true if the given method is overwritten by one of the ancestors in the ancestor change that comes before the given module
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/contrast/utils/class_util.rb', line 35 def prepended_method? mod, method_policy target_module = determine_target_class(mod, method_policy.instance_method) ancestors = target_module.ancestors return false unless prepended?(target_module, ancestors) ancestors.each do |ancestor| break if ancestor == target_module methods = ancestor.instance_methods(false) return true if methods.include?(method_policy.method_name) end false end |
.to_contrast_string(object) ⇒ String, Object
Return a String representing the object invoking this method in the form expected by our dataflow events. After implementing the LRU Cache, we firstly need to check if already had that object cached and if we have it - we can return it directly; otherwise we’ll calculate and store the result before returning.
Combining of the caches have close performance, but keeping the two with current implementation has a slight advantage in performance. For now we can keep the things the way they are.
59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/contrast/utils/class_util.rb', line 59 def to_contrast_string object # Only treat object like a string if it actually is a string+ some subclasses of String override string # methods we depend on if object.cs__class == String return @string_cache[object] if @string_cache.key?(object) @string_cache[object] = to_cached_string(object) || object.dup else return @lru_cache[object.__id__] if @lru_cache.key?(object.__id__) @lru_cache[object.__id__] = convert_object(object) end end |
.truly_defined?(name) ⇒ Boolean
The method Module.const_defined? can raise an exception if the constant is poorly named. As such, we need to handle the case where that exception is raised.
94 95 96 97 98 99 100 |
# File 'lib/contrast/utils/class_util.rb', line 94 def truly_defined? name return false unless name Module.cs__const_defined?(name) rescue NameError # account for nonsense / poorly formatted constants false end |