class ObjectIdentifier::Identifier

ObjectIdentifier::Identifier manages construction of the inspect String.

Constants

NO_OBJECTS_INDICATOR

Public Class Methods

identify(object, *args) click to toggle source

Class method for constructing a self-identifying string for any given object or collection of objects.

@overload self.identify(obj, *args)

@param obj [Object] the object to identify
@param args [*] (optional) a list of arguments to identify for this
  object or for each object in this collection

@overload self.identify(obj, *args, options)

@param obj [Object] the object to identify
@param args [*] (optional) (default :id) a list of arguments to identify
  for this object
@param [Hash] options the options for building a customized
  self-identifier
@option options [String, nil] :klass object class name override
@option options [Integer] :limit maximum number of objects to display
  from a collection

@return [String] a self-identifying string like `Class[id:1, name:'temp']`

@example

ObjectIdentifier::Identifier.identify(
  OpenStruct.new(a: 1, b: '2', c: :"3"), :a, :b, :c)
# => "OpenStruct[a:1, b:\"2\", c::\"3\"]"

ObjectIdentifier::Identifier.identify(1, :to_s)
# => "Integer[to_s:\"1\"]"
ObjectIdentifier::Identifier.identify(nil)
# => "[no objects]"

ObjectIdentifier::Identifier.identify(%w(1 2), :to_i, :to_f)
# => "String[to_i:1, to_f:1.0], String[to_i:2, to_f:2.0]"

ObjectIdentifier::Identifier.identify((1..10).to_a, :to_f, limit: 2)
# => "Integer[to_f:1.0], Integer[to_f:2.0], ... (8 more)"
# File lib/object_identifier/identifier.rb, line 42
def self.identify(object, *args)
  new(object, *args).to_s
end
new(objects, *args, limit: nil, klass: :not_given) click to toggle source
# File lib/object_identifier/identifier.rb, line 46
def initialize(objects, *args, limit: nil, klass: :not_given)
  @objects = ArrayWrap.call(objects)
  @attributes = args.empty? ? [:id] : args
  @limit = (limit || @objects.size).to_i
  @klass = klass
end

Public Instance Methods

to_s() click to toggle source

Output the self-identifying string for an instance of ObjectIdentifier::Identifier. Will either return a single object representation or a list of object representations, based on the number of objects we're identifying.

@return [String] a string representing the object or list of objects

# File lib/object_identifier/identifier.rb, line 59
def to_s
  if many?
    format_multiple_objects
  else
    format_single_object
  end
end

Private Instance Methods

blank?(object) click to toggle source
# File lib/object_identifier/identifier.rb, line 133
def blank?(object)
  object.nil? || object == [] || object == {}
end
class_name(object) click to toggle source
# File lib/object_identifier/identifier.rb, line 117
def class_name(object)
  klass_given? ? @klass : object.class.name
end
evaluate_attributes(object) click to toggle source

@return [Hash]

# File lib/object_identifier/identifier.rb, line 107
def evaluate_attributes(object)
  @attributes.each_with_object({}) { |key, acc|
    if object.respond_to?(key, :include_private)
      acc[key] = object.send(key)
    elsif key.to_s.start_with?("@")
      acc[key] = object.instance_variable_get(key)
    end
  }
end
format(object) click to toggle source
# File lib/object_identifier/identifier.rb, line 84
def format(object)
  return NO_OBJECTS_INDICATOR if blank?(object)

  "#{class_name(object)}[#{format_attributes(evaluate_attributes(object))}]"
end
format_attributes(attributes_hash) click to toggle source
# File lib/object_identifier/identifier.rb, line 90
def format_attributes(attributes_hash)
  return if attributes_hash.empty?

  attributes_hash.
    map(&format_attributes_map_block(attributes_hash)).
    join(", ")
end
format_attributes_map_block(attributes_hash) click to toggle source
# File lib/object_identifier/identifier.rb, line 98
def format_attributes_map_block(attributes_hash)
  if attributes_hash.one?
    ->(_key, value) { value.inspect_lit }
  else
    ->(key, value) { "#{key}:#{value.inspect_lit}" }
  end
end
format_multiple_objects() click to toggle source
# File lib/object_identifier/identifier.rb, line 69
def format_multiple_objects
  objects =
    @objects.first(@limit).map { |obj| format(obj) }

  objects << "... (#{truncated_objects_count} more)" if truncated?

  objects.join(", ")
end
format_single_object() click to toggle source
# File lib/object_identifier/identifier.rb, line 78
def format_single_object
  object = @objects.first if @objects.respond_to?(:first)

  format(object)
end
klass_given?() click to toggle source
# File lib/object_identifier/identifier.rb, line 129
def klass_given?
  @klass != :not_given
end
many?() click to toggle source
# File lib/object_identifier/identifier.rb, line 137
def many?
  objects_count > 1
end
objects_count() click to toggle source
# File lib/object_identifier/identifier.rb, line 125
def objects_count
  @objects_count ||= @objects.size
end
truncated?() click to toggle source
# File lib/object_identifier/identifier.rb, line 141
def truncated?
  truncated_objects_count.positive?
end
truncated_objects_count() click to toggle source
# File lib/object_identifier/identifier.rb, line 121
def truncated_objects_count
  objects_count - @limit
end