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
|