hashy_object 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Rakefile +17 -0
- data/hashy_object.gemspec +23 -0
- data/lib/hashy_object.rb +92 -0
- data/lib/hashy_object/version.rb +3 -0
- data/spec/hashy_object_spec.rb +98 -0
- data/spec/spec_helper.rb +12 -0
- metadata +78 -0
    
        data/.rvmrc
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            rvm use ruby-1.9.2-p290@hashy_object --create
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require "bundler/gem_tasks"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "bundler"
         | 
| 4 | 
            +
            Bundler.setup
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require "rspec"
         | 
| 7 | 
            +
            require "rspec/core/rake_task"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Bundler::GemHelper.install_tasks
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            task :default => :spec
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            RSpec::Core::RakeTask.new(:spec) do |spec|
         | 
| 16 | 
            +
              spec.pattern = 'spec/**/*_spec.rb'
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            +
            require "hashy_object/version"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |s|
         | 
| 6 | 
            +
              s.name        = "hashy_object"
         | 
| 7 | 
            +
              s.version     = HashyObject::VERSION
         | 
| 8 | 
            +
              s.authors     = ["Chris Apolzon"]
         | 
| 9 | 
            +
              s.email       = ["apolzon@gmail.com"]
         | 
| 10 | 
            +
              s.homepage    = ""
         | 
| 11 | 
            +
              s.summary     = %q{Generate a hash-like string representation of any Ruby object}
         | 
| 12 | 
            +
              s.description = %q{Generate a hash-like string representation of any Ruby object}
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              s.rubyforge_project = "hashy_object"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              s.files         = `git ls-files`.split("\n")
         | 
| 17 | 
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 18 | 
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 19 | 
            +
              s.require_paths = ["lib"]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              s.add_development_dependency "rspec"
         | 
| 22 | 
            +
              s.add_development_dependency "mocha"
         | 
| 23 | 
            +
            end
         | 
    
        data/lib/hashy_object.rb
    ADDED
    
    | @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            require "hashy_object/version"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class HashyObject
         | 
| 4 | 
            +
              class TooMuchRecursionException < Exception; end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              MAX_RECURSION_LEVELS = 100
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              attr_accessor :obj
         | 
| 9 | 
            +
              attr_accessor :recursion_level
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def initialize(obj, recursion_level = 0)
         | 
| 12 | 
            +
                raise TooMuchRecursionException if recursion_level > MAX_RECURSION_LEVELS
         | 
| 13 | 
            +
                self.obj = obj
         | 
| 14 | 
            +
                self.recursion_level = recursion_level
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def inspect
         | 
| 18 | 
            +
                return obj if obj.is_a?(String)
         | 
| 19 | 
            +
                return obj.inspect if inspectable?
         | 
| 20 | 
            +
                inspectify
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def inspectable?
         | 
| 24 | 
            +
                return true if obj.is_a?(String)
         | 
| 25 | 
            +
                inspected = obj.inspect
         | 
| 26 | 
            +
                return false if inspected.match /#</
         | 
| 27 | 
            +
                true
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def inspectify
         | 
| 31 | 
            +
                return handle_hashy_array(obj).inspect if obj.class == Array
         | 
| 32 | 
            +
                return handle_hashy_hash(obj).inspect if obj.class == Hash
         | 
| 33 | 
            +
                return handle_hashy_to_hash(obj).inspect if obj.respond_to?(:to_hash)
         | 
| 34 | 
            +
                return handle_hashy_instance_variables(obj).inspect
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def handle_hashy_array(obj)
         | 
| 40 | 
            +
                [].tap do |out|
         | 
| 41 | 
            +
                  obj.each_with_index do |element, index|
         | 
| 42 | 
            +
                    hashy_element = HashyObject.new(element, recursion_level + 1)
         | 
| 43 | 
            +
                    if hashy_element.inspectable?
         | 
| 44 | 
            +
                      hashy_element = nil
         | 
| 45 | 
            +
                      out[index] = element
         | 
| 46 | 
            +
                    else
         | 
| 47 | 
            +
                      out[index] = hashy_element
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def handle_hashy_hash(obj)
         | 
| 54 | 
            +
                {}.tap do |out|
         | 
| 55 | 
            +
                  obj.each_pair do |key, value|
         | 
| 56 | 
            +
                    hashy_value = HashyObject.new(value, recursion_level + 1)
         | 
| 57 | 
            +
                    if hashy_value.inspectable?
         | 
| 58 | 
            +
                      hashy_value = nil
         | 
| 59 | 
            +
                      out[key] = value
         | 
| 60 | 
            +
                    else
         | 
| 61 | 
            +
                      out[key] = hashy_value
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def handle_hashy_to_hash(obj)
         | 
| 68 | 
            +
                obj_hash = obj.to_hash
         | 
| 69 | 
            +
                if obj_hash.inspect.match(/#</)
         | 
| 70 | 
            +
                  obj_hash.each_pair do |key, value|
         | 
| 71 | 
            +
                    next unless value.inspect.match /#</
         | 
| 72 | 
            +
                    hashy_value = HashyObject.new(value, recursion_level + 1)
         | 
| 73 | 
            +
                    obj_hash[key] = hashy_value.inspect
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
                obj_hash
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              def handle_hashy_instance_variables(obj)
         | 
| 80 | 
            +
                out = {}
         | 
| 81 | 
            +
                obj.instance_variables.each do |var|
         | 
| 82 | 
            +
                  hashy_var = HashyObject.new(obj.instance_variable_get(var), recursion_level + 1)
         | 
| 83 | 
            +
                  if hashy_var.inspectable?
         | 
| 84 | 
            +
                    hashy_var = nil
         | 
| 85 | 
            +
                    out[var] = obj.instance_variable_get(var)
         | 
| 86 | 
            +
                  else
         | 
| 87 | 
            +
                    out[var] = hashy_var
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
                out
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| @@ -0,0 +1,98 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe HashyObject do
         | 
| 4 | 
            +
              describe "initialize" do
         | 
| 5 | 
            +
                it "raises a TooMuchRecursionException when initializing with too high a recursion_level" do
         | 
| 6 | 
            +
                  expect {
         | 
| 7 | 
            +
                    HashyObject.new("my string", HashyObject::MAX_RECURSION_LEVELS + 1)
         | 
| 8 | 
            +
                  }.to raise_error(::HashyObject::TooMuchRecursionException)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              context "with a string" do
         | 
| 13 | 
            +
                specify {
         | 
| 14 | 
            +
                  HashyObject.new("my string").inspect.should == "my string"
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              context "with a hash" do
         | 
| 19 | 
            +
                specify {
         | 
| 20 | 
            +
                  HashyObject.new({}).inspect.should == "{}"
         | 
| 21 | 
            +
                }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                specify {
         | 
| 24 | 
            +
                  HashyObject.new({:a => 1, :b => 2}).inspect.should == "{:a=>1, :b=>2}"
         | 
| 25 | 
            +
                }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                specify {
         | 
| 28 | 
            +
                  HashyObject.new({:a => {:a => "string me", 'b' => 'i gots me a string key'}, 'other key' => 5}).inspect.should ==
         | 
| 29 | 
            +
                    '{:a=>{:a=>"string me", "b"=>"i gots me a string key"}, "other key"=>5}'
         | 
| 30 | 
            +
                }
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              context "with a dumb class" do
         | 
| 34 | 
            +
                specify {
         | 
| 35 | 
            +
                  HashyObject.new(NoDecoration.new).inspect.should == "{:@a=>1}"
         | 
| 36 | 
            +
                }
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              context "with a deeply embedded dumb class" do
         | 
| 40 | 
            +
                specify {
         | 
| 41 | 
            +
                  HashyObject.new(NoDecorationContainer.new).inspect.should == "{:@b=>{:@a=>1}}"
         | 
| 42 | 
            +
                }
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              context "with an array of dumb classes" do
         | 
| 46 | 
            +
                specify {
         | 
| 47 | 
            +
                  HashyObject.new([NoDecoration.new]).inspect.should == "[{:@a=>1}]"
         | 
| 48 | 
            +
                }
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              context "with a hash of dumb classes" do
         | 
| 52 | 
            +
                specify {
         | 
| 53 | 
            +
                  HashyObject.new({:a => NoDecoration.new}).inspect.should == "{:a=>{:@a=>1}}"
         | 
| 54 | 
            +
                }
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              context "with a properly decorated class"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              describe "#inspectable" do
         | 
| 60 | 
            +
                specify {
         | 
| 61 | 
            +
                  HashyObject.new("face").should be_inspectable
         | 
| 62 | 
            +
                }
         | 
| 63 | 
            +
                specify {
         | 
| 64 | 
            +
                  HashyObject.new({:a=>1}).should be_inspectable
         | 
| 65 | 
            +
                }
         | 
| 66 | 
            +
                specify {
         | 
| 67 | 
            +
                  HashyObject.new(%W(a b c d e f g)).should be_inspectable
         | 
| 68 | 
            +
                }
         | 
| 69 | 
            +
                specify {
         | 
| 70 | 
            +
                  HashyObject.new(NoDecoration.new).should_not be_inspectable
         | 
| 71 | 
            +
                }
         | 
| 72 | 
            +
                specify {
         | 
| 73 | 
            +
                  HashyObject.new(WithDecoration.new).should be_inspectable
         | 
| 74 | 
            +
                }
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                specify {
         | 
| 77 | 
            +
                  HashyObject.new([NoDecoration.new]).should_not be_inspectable
         | 
| 78 | 
            +
                }
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
            end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            class NoDecoration
         | 
| 83 | 
            +
              def initialize
         | 
| 84 | 
            +
                @a = 1
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            class WithDecoration < NoDecoration
         | 
| 89 | 
            +
              def inspect
         | 
| 90 | 
            +
                {:a => @a}.inspect
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            class NoDecorationContainer
         | 
| 95 | 
            +
              def initialize
         | 
| 96 | 
            +
                @b = NoDecoration.new
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            require 'bundler'
         | 
| 2 | 
            +
            Bundler.require
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'hashy_object'
         | 
| 5 | 
            +
            require 'rspec'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            #require 'active_support/string_inquirer'
         | 
| 8 | 
            +
            Dir[File.expand_path(File.join(File.dirname(__FILE__), "support/**/*.rb"))].each { |f| require f }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            RSpec.configure do |config|
         | 
| 11 | 
            +
              config.mock_with :mocha
         | 
| 12 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: hashy_object
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
            platform: ruby
         | 
| 7 | 
            +
            authors:
         | 
| 8 | 
            +
            - Chris Apolzon
         | 
| 9 | 
            +
            autorequire: 
         | 
| 10 | 
            +
            bindir: bin
         | 
| 11 | 
            +
            cert_chain: []
         | 
| 12 | 
            +
            date: 2012-02-22 00:00:00.000000000Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            +
              name: rspec
         | 
| 16 | 
            +
              requirement: &70175290902600 !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                none: false
         | 
| 18 | 
            +
                requirements:
         | 
| 19 | 
            +
                - - ! '>='
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            +
                    version: '0'
         | 
| 22 | 
            +
              type: :development
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              version_requirements: *70175290902600
         | 
| 25 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 26 | 
            +
              name: mocha
         | 
| 27 | 
            +
              requirement: &70175290902180 !ruby/object:Gem::Requirement
         | 
| 28 | 
            +
                none: false
         | 
| 29 | 
            +
                requirements:
         | 
| 30 | 
            +
                - - ! '>='
         | 
| 31 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            +
                    version: '0'
         | 
| 33 | 
            +
              type: :development
         | 
| 34 | 
            +
              prerelease: false
         | 
| 35 | 
            +
              version_requirements: *70175290902180
         | 
| 36 | 
            +
            description: Generate a hash-like string representation of any Ruby object
         | 
| 37 | 
            +
            email:
         | 
| 38 | 
            +
            - apolzon@gmail.com
         | 
| 39 | 
            +
            executables: []
         | 
| 40 | 
            +
            extensions: []
         | 
| 41 | 
            +
            extra_rdoc_files: []
         | 
| 42 | 
            +
            files:
         | 
| 43 | 
            +
            - .gitignore
         | 
| 44 | 
            +
            - .rvmrc
         | 
| 45 | 
            +
            - Gemfile
         | 
| 46 | 
            +
            - Rakefile
         | 
| 47 | 
            +
            - hashy_object.gemspec
         | 
| 48 | 
            +
            - lib/hashy_object.rb
         | 
| 49 | 
            +
            - lib/hashy_object/version.rb
         | 
| 50 | 
            +
            - spec/hashy_object_spec.rb
         | 
| 51 | 
            +
            - spec/spec_helper.rb
         | 
| 52 | 
            +
            homepage: ''
         | 
| 53 | 
            +
            licenses: []
         | 
| 54 | 
            +
            post_install_message: 
         | 
| 55 | 
            +
            rdoc_options: []
         | 
| 56 | 
            +
            require_paths:
         | 
| 57 | 
            +
            - lib
         | 
| 58 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 59 | 
            +
              none: false
         | 
| 60 | 
            +
              requirements:
         | 
| 61 | 
            +
              - - ! '>='
         | 
| 62 | 
            +
                - !ruby/object:Gem::Version
         | 
| 63 | 
            +
                  version: '0'
         | 
| 64 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
              none: false
         | 
| 66 | 
            +
              requirements:
         | 
| 67 | 
            +
              - - ! '>='
         | 
| 68 | 
            +
                - !ruby/object:Gem::Version
         | 
| 69 | 
            +
                  version: '0'
         | 
| 70 | 
            +
            requirements: []
         | 
| 71 | 
            +
            rubyforge_project: hashy_object
         | 
| 72 | 
            +
            rubygems_version: 1.8.15
         | 
| 73 | 
            +
            signing_key: 
         | 
| 74 | 
            +
            specification_version: 3
         | 
| 75 | 
            +
            summary: Generate a hash-like string representation of any Ruby object
         | 
| 76 | 
            +
            test_files:
         | 
| 77 | 
            +
            - spec/hashy_object_spec.rb
         | 
| 78 | 
            +
            - spec/spec_helper.rb
         |