Object Identifier

Gem Version Build Status Test Coverage Maintainability

Object Identifier allows quick, easy, and uniform identification of an object by inspecting its class name and outputting any desirable attributes/methods. It is great for logging, sending descriptive notification messages, etc.

For example:

some_object.identify(:id, :name)

Which is the same as:

"#{some_object.class.name}[id:#{some_object.id}, name:\"#{some_object.name}\"]"

Installation

Add this line to your application's Gemfile:

gem "object_identifier"

And then execute:

$ bundle

Or install it yourself as:

$ gem install object_identifier

Compatibility

Tested MRI Ruby Versions:

  • 2.2.10
  • 2.3.7
  • 2.4.4
  • 2.5.1
  • edge

Usage

Defaults

identify outputs the id of the receiving object by default, if it exists and no other attributes/methods are specified.

my_movie.identify           # => Movie[id:1]
my_movie.identify(:rating)  # => Movie[rating:"7/10"]

Private methods can be identified just the same as public methods.

my_movie.identify(:my_private_method)  # => Movie[my_private_method:"Shh"]

Unknown Attributes/Methods

If the object doesn't respond to a specified attribute/method it is simply ignored:

my_movie.identify(:gobble_gobble, :rating)  # => Movie[rating:"7/10"]

Overriding Class Names

my_delayed_job.identify(klass: "Delayed::Job")  # => Delayed::Job[id:1]
my_movie.identify(klass: nil)                   # => [id:1]

Identifying Nil

nil.identify(:id, :name)                 # => [no objects]
nil.identify(:id, :name, klass: "Nope")  # => [no objects]

Collections

Collections of objects are each identified in turn.

[my_movie, my_user].identify(:id, :name)
# => Movie[id:1, name:"Pi"], User[id:1, name:"Bob"]

The number of results that will be identified from a collection can be truncated by specifying the limit option.

[my_movie, my_contact].identify(:id, :name, limit: 1)
# => Movie[id:1, name:"Pi"], ... (1 more)

Empty Collections

[].identify  # => [no objects]
{}.identify  # => [no objects]

Custom Object Identifiers

Internally, Object Identifier calls inspect_lit to return a "literally-inspected" string representation of an object. This works because Object, itself, is monkey-patched to define inspect_lit which just returns inspect. This is sufficient for most objects, but some objects will benefit from defining special output from inspect_lit.

Object Identifier defines inspect_lit on three other core objects: String, Symbol, and BigDecimal.

"a_string".inspect_lit           # => "\"a_string\""
:a_symbol.inspect_lit            # => ":\"a_symbol\""
BigDecimal(1.99, 3).inspect_lit  # => "<BD:1.99>"

To identify an object in a special way, just define inspect_lit to return a custom String.

class MyValueObject
  def initialize(val)
    @val = val
  end

  def inspect_lit
    "#{@val} Meters"
  end
end

my_value_object = MyValueObject.new(42)
OpenStruct.new(my_value: my_value_object).identify(:my_value)
# => "OpenStruct[my_value:42 Meters]"

Supporting Gems

ObjectIdentifier works great with the ObjectInspector gem.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/pdobb/object_identifier.

License

The gem is available as open source under the terms of the MIT License.