Ishin
Ishin converts Ruby objects into their Hash representations. It works with plain old classes, extended classes, classes with mixins, and hashes (see Usage for more information).
Installation
Add this line to your application's Gemfile:
gem 'ishin'
And then execute:
bundle
Or install it manually by:
gem install ishin
Requirements
Ishin does not require any other gems to run. There are a few gems used during
development only, but don't affect runtime performance. For details, see
ishin.gemspec
in the root directory of the project.
Example
As a class method callable on any object:
require 'ishin'
hash = Ishin.to_hash(my_object)
Or included in your object as a mixin:
class YourClass
include Ishin::Mixin
# etc.
end
instance = YourClass.new
hash = instance.to_hash
Usage
A simple example is worth a thousand words:
class Animal
attr_reader :leg_count
def initialize leg_count
@leg_count = leg_count
end
end
dog = Animal.new(4)
dog_hash = Ishin.to_hash(dog)
# => {:leg_count=>4}
Recursion
Ishin also handles object instances nested within other object instances. By
default, recursive hash conversion is turned off. To enable recursion, set the
recursive
option to true
:
test_struct = Struct.new(:value)
nested_structs = test_struct.new(test_struct.new('value'))
Ishin.to_hash(nested_structs, recursive: true)
# => {:value=>{:value=>"value"}}
Recursion Depth
For deeply nested object instances, a maximum recursion depth can be provided in
combination with the recursive
option. The default recursion depth is one
(initial call + 1).
nest_me = Struct.new(:value)
deep_nesting = nest_me.new(nest_me.new(nest_me.new(nest_me.new('such depth'))))
Ishin.to_hash(deep_nesting, recursive: true, recursion_depth: 2)
# => {:value=>{:value=>{:value=>#<struct value="such depth">}}}
Notice in the above example that the recursion stopped after 3 steps (initial call + 2).
Warning: Increasing the recursion depth will affect the runtime of the
conversion process significantly. To see how drastic increased recursion levels
affect performance, run ruby benchmarks/recursive_bench.rb
Expanding Hashes using Recursion
Using recursion, it is also possible to convert hashes containing object
instances to a hash-only representation as well. Notice that this only works if
the recursive
option is provided.
another_struct = Struct.new(:value)
my_hash = {
my_struct: another_struct.new("yup, it's a struct")
}
Ishin.to_hash(my_hash, recursive: true)
# => {:my_struct=>{:value=>"yup, it's a struct"}}
Keep in mind that the recursive
option works in conjunction with the
recursion_depth
option.
Symbolizing Keys
By default, Ishin stores key names as symbols. This behavior can be disabled by
setting the symbolize
option to false
.
class Dog
attr_reader :says
def initialize(says)
@says = says
end
end
lassie = Dog.new('Timmy is stuck in a well!')
Ishin.to_hash(lassie)
# => {:says=>"Timmy is stuck in a well!"}
Ishin.to_hash(lassie, symbolize: false)
# => {"says"=>"Timmy is stuck in a well!"}
When setting the symbolize
option to false
, the explicit conversion of
strings to symbols is prevented. This, however, does not mean that hashes
whose keys are already symbols are converted into string-based keys.
Evaluating Methods
Normally, Ishin does not evaluate methods, but is possible to do so through the
optional evaluate
option by passing it an array of method names to evaluate.
class Speaker
def say
"Say what?"
end
end
speaker = Speaker.new
# => #<Speaker:0x007fb2bb1812d8>
Ishin.to_hash(speaker, evaluate: [ :say ])
# => {:say=>"Say what?"}
It is currently only possible to evaluate methods that do not require arguments.
As a Mixin
To use Ishin as a mixin in your own objects, simply include Ishin::Mixin
:
class MyObject
include Ishin::Mixin
# etc.
end
Your object now exposes a method named to_hash
taking the same options at the
Ishin::to_hash
class method documented above.
Running Code Quality Tools
To run the code quality tools Rubocop, Reek, and RSpec, run the following command:
rake
Running the Specs
Once bundle
is executed, simply run:
rake spec
Running the Benchmarks
To give an idea on what kind of performance can be expected from Ishin, there
are a few IPS (iterations per second) benchmarks located in the benchmarks
directory. These can all be executed in series by running:
rake bench
Changelog
- 0.1.0
- Initial release.
- 0.2.0
- Added
Ishin::Mixin
.
- Added
- 0.2.1
- Now using
Struct.to_h
when converting aStruct
instance.
- Now using
- 0.3.0
- Added support for evaluating object methods.
- 0.4.0
- Cleanup: preparing an overhaul