Class: SleepingKingStudios::Tools::ObjectTools

Inherits:
Base
  • Object
show all
Defined in:
lib/sleeping_king_studios/tools/object_tools.rb

Overview

Low-level tools for working with objects.

Instance Method Summary collapse

Methods inherited from Base

instance

Instance Method Details

#apply(receiver, proc, *args, **kwargs, &block) ⇒ Object

Takes a proc or lambda and invokes it with the given object as receiver, with any additional arguments or block provided.

Parameters:

  • receiver (Object)

    The receiver. The proc will be called in the context of this object.

  • proc (Proc)

    The proc or lambda to call.

  • args (Array)

    Optional. Additional arguments to pass in to the proc or lambda.

  • kwargs (Hash)

    Optional. Additional keywords to pass in to the proc or lambda.

  • block (block)

    Optional. If present, will be passed in to proc or lambda.

Returns:

  • The result of calling the proc or lambda with the given receiver and any additional arguments or block.



41
42
43
44
45
46
47
48
49
50
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 41

def apply(receiver, proc, *args, **kwargs, &block)
  return receiver.instance_exec(*args, **kwargs, &proc) unless block_given?

  method_name =
    Kernel.format(TEMPORARY_METHOD_NAME, Thread.current.object_id)

  with_temporary_method(receiver, method_name, proc) do
    receiver.send(method_name, *args, **kwargs, &block)
  end
end

#deep_dup(obj) ⇒ Object

Creates a deep copy of the object. If the object is an Array, returns a new Array with deep copies of each array item. If the object is a Hash, returns a new Hash with deep copies of each hash key and value. Otherwise, returns Object#dup.

Parameters:

  • obj (Object)

    The object to copy.

Returns:

  • The copy of the object.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 60

def deep_dup(obj)
  case obj
  when FalseClass, Integer, Float, NilClass, Symbol, TrueClass
    obj
  when ->(_) { ArrayTools.array?(obj) }
    ArrayTools.deep_dup obj
  when ->(_) { HashTools.hash?(obj) }
    HashTools.deep_dup obj
  else
    obj.respond_to?(:deep_dup) ? obj.deep_dup : obj.dup
  end
end

#deep_freeze(obj) ⇒ Object

Performs a deep freeze of the object. If the object is an Array, freezes the array and performs a deep freeze on each array item. If the object is a hash, freezes the hash and performs a deep freeze on each hash key and value. Otherwise, calls Object#freeze.

Parameters:

  • obj (Object)

    The object to freeze.



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 79

def deep_freeze(obj)
  case obj
  when FalseClass, Integer, Float, NilClass, Symbol, TrueClass
    # Object is inherently immutable; do nothing here.
  when ->(_) { ArrayTools.array?(obj) }
    ArrayTools.deep_freeze(obj)
  when ->(_) { HashTools.hash?(obj) }
    HashTools.deep_freeze obj
  else
    obj.respond_to?(:deep_freeze) ? obj.deep_freeze : obj.freeze
  end
end

#dig(object, *method_names) ⇒ Object

Accesses deeply nested attributes by calling the first named method on the given object, and each subsequent method on the result of the previous method call. If the object does not respond to the method name, nil is returned instead of calling the method.

Parameters:

  • object (Object)

    The object to dig.

  • method_names (Array)

    The names of the methods to call.

Returns:

  • (Object)

    The result of the last method call, or nil if the last object does not respond to the last method.



102
103
104
105
106
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 102

def dig(object, *method_names)
  method_names.reduce(object) do |memo, method_name|
    memo.respond_to?(method_name) ? memo.send(method_name) : nil
  end
end

#eigenclass(object) ⇒ Class Also known as: metaclass

Returns the object’s eigenclass.

Parameters:

  • object (Object)

    The object for which an eigenclass is required.

Returns:

  • (Class)

    The object’s singleton class.



120
121
122
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 120

def eigenclass(object)
  object.singleton_class
end

#immutable?(obj) ⇒ Boolean

Returns true if the object is immutable. Values of nil, false, and true are always immutable, as are instances of Numeric and Symbol. Arrays are immutable if the array is frozen and each array item is immutable. Hashes are immutable if the hash is frozen and each hash key and hash value are immutable. Otherwise, objects are immutable if they are frozen.

Parameters:

  • obj (Object)

    The object to test.

Returns:

  • (Boolean)

    True if the object is immutable, otherwise false.



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 134

def immutable?(obj)
  case obj
  when NilClass, FalseClass, TrueClass, Numeric, Symbol
    true
  when ->(_) { ArrayTools.array?(obj) }
    ArrayTools.immutable? obj
  when ->(_) { HashTools.hash?(obj) }
    HashTools.immutable? obj
  else
    obj.frozen?
  end
end

#mutable?(obj) ⇒ Boolean

Returns true if the object is mutable.

Parameters:

  • obj (Object)

    The object to test.

Returns:

  • (Boolean)

    True if the object is mutable, otherwise false.

See Also:



154
155
156
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 154

def mutable?(obj)
  !immutable?(obj)
end

#object?(obj) ⇒ Boolean

Returns true if the object is an Object. This should return true only for objects that have an alternate inheritance chain from BasicObject, such as a Proxy.

Parameters:

  • obj (Object)

    The object to test.

Returns:

  • (Boolean)

    True if the object is an Object, otherwise false.



165
166
167
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 165

def object?(obj)
  Object.instance_method(:is_a?).bind(obj).call(Object)
end

#try(object, method_name, *args) ⇒ Object

As #send, but returns nil if the object does not respond to the method.

Parameters:

  • object (Object)

    The receiver of the message.

  • method_name (String, Symbol)

    The name of the method to call.

  • args (Array)

    The arguments to the message.

See Also:

  • ActiveSupport::CoreExt::Object#try.


176
177
178
179
180
181
182
# File 'lib/sleeping_king_studios/tools/object_tools.rb', line 176

def try(object, method_name, *args)
  return object.try(method_name, *args) if object.respond_to?(:try)

  return nil unless object.respond_to?(method_name)

  object.send method_name, *args
end