hashify 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/README.rdoc +47 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/lib/hashify.rb +55 -0
- data/lib/hashify/convert.rb +6 -0
- data/lib/hashify/json.rb +18 -0
- data/spec/convert_spec.rb +20 -0
- data/spec/from_hash_spec.rb +61 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/to_hash_spec.rb +62 -0
- metadata +68 -0
data/README.rdoc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= Hashify
|
2
|
+
|
3
|
+
Utterly simple hash creation for the your favorite objects
|
4
|
+
|
5
|
+
== Usage
|
6
|
+
|
7
|
+
class Person
|
8
|
+
include Hashify
|
9
|
+
|
10
|
+
attr_accessor :name, :address, :date_of_birth
|
11
|
+
hash_accessor :name, :address
|
12
|
+
end
|
13
|
+
|
14
|
+
>> p = Person.new
|
15
|
+
>> p.name = 'my name'
|
16
|
+
>> p.address = 'my address'
|
17
|
+
>> p.to_hash
|
18
|
+
=> {:name=>"my name", :address=>"my address"}
|
19
|
+
|
20
|
+
What about that pesky dob?
|
21
|
+
|
22
|
+
class Person
|
23
|
+
hash_convert :date_of_birth => Hashify::Convert::Time
|
24
|
+
end
|
25
|
+
|
26
|
+
>> p.date_of_birth = Time.local(2000, "jan", 1, 0, 0, 0)
|
27
|
+
>> p.to_hash
|
28
|
+
=> {:date_of_birth=>946702800, :name=>"my name", :address=>"my address"}
|
29
|
+
|
30
|
+
How we have these beautiful hashes, lets get a person back out of it.
|
31
|
+
|
32
|
+
>> Person.from_hash(:date_of_birth=>946702800, :name=>"my name", :address=>"my address")
|
33
|
+
=> #<Person:0x10187b660 @date_of_birth=Sat Jan 01 00:00:00 -0500 2000, @address="my address", @name="my name">
|
34
|
+
|
35
|
+
For bonus points, lets do json too
|
36
|
+
|
37
|
+
class Person
|
38
|
+
include Hashify::Json
|
39
|
+
end
|
40
|
+
|
41
|
+
>> p.to_json
|
42
|
+
=> "{\"address\":\"my address\",\"date_of_birth\":946702800,\"name\":\"my name\"}"
|
43
|
+
|
44
|
+
And of course,
|
45
|
+
|
46
|
+
>> Person.from_json("{\"address\":\"my address\",\"date_of_birth\":946702800,\"name\":\"my name\"}")
|
47
|
+
=> #<Person:0x101809150 @date_of_birth=Sat Jan 01 00:00:00 -0500 2000, @address="my address", @name="my name">
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
libdir = File.expand_path("lib")
|
2
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
3
|
+
|
4
|
+
require 'hashify'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = "hashify"
|
10
|
+
s.description = s.summary = "Simple to_hash, to_json <-> from_hash, from_json"
|
11
|
+
s.email = "joshbuddy@gmail.com"
|
12
|
+
s.homepage = "http://github.com/joshbuddy/hashify"
|
13
|
+
s.authors = ["Joshua Hull"]
|
14
|
+
s.files = FileList["[A-Z]*", "{lib,spec}/**/*"]
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec'
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
task :spec => 'spec:all'
|
24
|
+
namespace(:spec) do
|
25
|
+
Spec::Rake::SpecTask.new(:all) do |t|
|
26
|
+
t.spec_opts ||= []
|
27
|
+
t.spec_opts << "-rubygems"
|
28
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
29
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Run all examples with RCov"
|
35
|
+
Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
|
36
|
+
t.spec_files = FileList['spec/**/*.rb']
|
37
|
+
t.rcov = true
|
38
|
+
t.rcov_opts = ['--exclude', 'spec']
|
39
|
+
end
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
desc "Generate documentation"
|
43
|
+
Rake::RDocTask.new do |rd|
|
44
|
+
rd.main = "README.rdoc"
|
45
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
46
|
+
rd.rdoc_dir = 'rdoc'
|
47
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/hashify.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Hashify
|
2
|
+
|
3
|
+
autoload :Json, File.join(File.dirname(__FILE__), 'hashify', 'json')
|
4
|
+
autoload :Convert, File.join(File.dirname(__FILE__), 'hashify', 'convert')
|
5
|
+
|
6
|
+
def self.included(cls)
|
7
|
+
|
8
|
+
cls.const_set(:HashConvertTable, {}) unless cls.const_defined?(:HashConvertTable)
|
9
|
+
cls.instance_eval(<<-CLASS_DOC, __FILE__, __LINE__)
|
10
|
+
def self.hash_convert_table
|
11
|
+
self.const_set(:HashConvertTable, {}) unless self.const_defined?(:HashConvertTable)
|
12
|
+
send(:const_get, :HashConvertTable)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.hash_accessor(*args)
|
16
|
+
args.each {|a| hash_convert_table[a] = nil }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.hash_convert(map)
|
20
|
+
hash_convert_table.merge!(map)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_hash(map)
|
24
|
+
convert_map = assembled_hash_convert
|
25
|
+
instance = new
|
26
|
+
map.each do |name, val|
|
27
|
+
convert_map[name.to_sym] ?
|
28
|
+
instance.send((name.to_s + '=').to_sym, convert_map[name.to_sym].last.call(val)) :
|
29
|
+
instance.send((name.to_s + '=').to_sym, val)
|
30
|
+
end
|
31
|
+
instance
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.assembled_hash_convert
|
35
|
+
map = hash_convert_table.dup
|
36
|
+
parent = self.superclass
|
37
|
+
while (parent and parent.respond_to?(:hash_convert_table))
|
38
|
+
map.merge!(parent.hash_convert_table) {|key, old_value, new_value| old_value || new_value }
|
39
|
+
parent = parent.superclass
|
40
|
+
end
|
41
|
+
map
|
42
|
+
end
|
43
|
+
CLASS_DOC
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_hash
|
47
|
+
self.class.assembled_hash_convert.inject({}) do |hash, (name, converter)|
|
48
|
+
converter ?
|
49
|
+
hash[name] = converter.first.call(self.send(name)) :
|
50
|
+
hash[name] = self.send(name)
|
51
|
+
hash
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/lib/hashify/json.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'json' unless Object.respond_to?(:to_json)
|
2
|
+
|
3
|
+
module Hashify
|
4
|
+
module Json
|
5
|
+
def self.included(cls)
|
6
|
+
cls.instance_eval "
|
7
|
+
def self.from_json(json)
|
8
|
+
from_hash(JSON.parse(json))
|
9
|
+
end
|
10
|
+
"
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_json
|
14
|
+
to_hash.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe "Basic object", "conversions" do
|
4
|
+
it "should run conversions" do
|
5
|
+
|
6
|
+
test = Class.new do
|
7
|
+
include Hashify
|
8
|
+
attr_accessor :prop1
|
9
|
+
hash_convert :prop1 => [proc{|x| x.to_i}, proc{|x| Time.at(x)}]
|
10
|
+
end
|
11
|
+
|
12
|
+
t = test.from_hash(:prop1 => 12345)
|
13
|
+
|
14
|
+
t.prop1.should == Time.at(12345)
|
15
|
+
|
16
|
+
t.to_hash.should == {:prop1 => 12345}
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe "Basic object", "from_hash" do
|
4
|
+
it "should convert from a hash" do
|
5
|
+
|
6
|
+
test = Class.new do
|
7
|
+
include Hashify
|
8
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
9
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
10
|
+
end
|
11
|
+
|
12
|
+
t = test.from_hash(:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4')
|
13
|
+
|
14
|
+
t.prop1.should == "prop_val_1"
|
15
|
+
t.prop2.should == "prop_val_2"
|
16
|
+
t.prop3.should == "prop_val_3"
|
17
|
+
t.prop4.should == "prop_val_4"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should convert from a hash for a subclass" do
|
21
|
+
|
22
|
+
test = Class.new do
|
23
|
+
include Hashify
|
24
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
25
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
26
|
+
end
|
27
|
+
|
28
|
+
test2 = Class.new(test)
|
29
|
+
|
30
|
+
t = test2.from_hash(:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4')
|
31
|
+
|
32
|
+
t.prop1.should == "prop_val_1"
|
33
|
+
t.prop2.should == "prop_val_2"
|
34
|
+
t.prop3.should == "prop_val_3"
|
35
|
+
t.prop4.should == "prop_val_4"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should convert from a hash for subclasses with specific hash accessors" do
|
39
|
+
|
40
|
+
test = Class.new do
|
41
|
+
include Hashify
|
42
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
43
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
44
|
+
end
|
45
|
+
|
46
|
+
test2 = Class.new(test) do
|
47
|
+
attr_accessor :prop5, :prop6
|
48
|
+
hash_accessor :prop5, :prop6
|
49
|
+
end
|
50
|
+
|
51
|
+
t = test2.from_hash(:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4', :prop5 => 'prop_val_5', :prop6 => 'prop_val_6')
|
52
|
+
t.prop1.should == "prop_val_1"
|
53
|
+
t.prop2.should == "prop_val_2"
|
54
|
+
t.prop3.should == "prop_val_3"
|
55
|
+
t.prop4.should == "prop_val_4"
|
56
|
+
t.prop5.should == "prop_val_5"
|
57
|
+
t.prop6.should == "prop_val_6"
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe "Basic object", 'to_hash' do
|
4
|
+
it "should convert into a hash" do
|
5
|
+
|
6
|
+
test = Class.new do
|
7
|
+
include Hashify
|
8
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
9
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
10
|
+
end
|
11
|
+
|
12
|
+
t = test.new
|
13
|
+
t.prop1 = "prop_val_1"
|
14
|
+
t.prop2 = "prop_val_2"
|
15
|
+
t.prop3 = "prop_val_3"
|
16
|
+
t.prop4 = "prop_val_4"
|
17
|
+
t.to_hash.should == {:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4'}
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should convert into a hash for subclasses" do
|
21
|
+
|
22
|
+
test = Class.new do
|
23
|
+
include Hashify
|
24
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
25
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
26
|
+
end
|
27
|
+
|
28
|
+
test2 = Class.new(test) do
|
29
|
+
end
|
30
|
+
|
31
|
+
t = test2.new
|
32
|
+
t.prop1 = "prop_val_1"
|
33
|
+
t.prop2 = "prop_val_2"
|
34
|
+
t.prop3 = "prop_val_3"
|
35
|
+
t.prop4 = "prop_val_4"
|
36
|
+
t.to_hash.should == {:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4'}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should convert into a hash for subclasses with specific hash accessors" do
|
40
|
+
|
41
|
+
test = Class.new do
|
42
|
+
include Hashify
|
43
|
+
attr_accessor :prop1, :prop2, :prop3, :prop4
|
44
|
+
hash_accessor :prop1, :prop2, :prop3, :prop4
|
45
|
+
end
|
46
|
+
|
47
|
+
test2 = Class.new(test) do
|
48
|
+
attr_accessor :prop5, :prop6
|
49
|
+
hash_accessor :prop5, :prop6
|
50
|
+
end
|
51
|
+
|
52
|
+
t = test2.new
|
53
|
+
t.prop1 = "prop_val_1"
|
54
|
+
t.prop2 = "prop_val_2"
|
55
|
+
t.prop3 = "prop_val_3"
|
56
|
+
t.prop4 = "prop_val_4"
|
57
|
+
t.prop5 = "prop_val_5"
|
58
|
+
t.prop6 = "prop_val_6"
|
59
|
+
t.to_hash.should == {:prop1 => 'prop_val_1', :prop2 => 'prop_val_2', :prop3 => 'prop_val_3', :prop4 => 'prop_val_4', :prop5 => 'prop_val_5', :prop6 => 'prop_val_6'}
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hashify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Hull
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-31 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Simple to_hash, to_json <-> from_hash, from_json
|
17
|
+
email: joshbuddy@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- VERSION
|
28
|
+
- lib/hashify.rb
|
29
|
+
- lib/hashify/convert.rb
|
30
|
+
- lib/hashify/json.rb
|
31
|
+
- spec/convert_spec.rb
|
32
|
+
- spec/from_hash_spec.rb
|
33
|
+
- spec/spec.opts
|
34
|
+
- spec/spec_helper.rb
|
35
|
+
- spec/to_hash_spec.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/joshbuddy/hashify
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.3.5
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: Simple to_hash, to_json <-> from_hash, from_json
|
64
|
+
test_files:
|
65
|
+
- spec/convert_spec.rb
|
66
|
+
- spec/from_hash_spec.rb
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
- spec/to_hash_spec.rb
|