dlt-mosh 0.2.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.
Files changed (5) hide show
  1. data/README +66 -0
  2. data/mosh.gemspec +12 -0
  3. data/mosh.rb +94 -0
  4. data/specs/mosh_spec.rb +65 -0
  5. metadata +57 -0
data/README ADDED
@@ -0,0 +1,66 @@
1
+ = Mosh (My Own Hash With Methods)
2
+
3
+ http://github.com/dlt/Mosh
4
+
5
+ == DESCRIPTION:
6
+
7
+ Mosh is my own version of mash (http://github.com/mbleigh/mash/).
8
+ I prefered to avoid method_missing and instead used instance_eval
9
+ for creating methods.
10
+ This library can be useful when you need to have hashes that look like
11
+ objects.
12
+
13
+ == SYNOPSIS:
14
+
15
+ mosh = Mosh.new
16
+ mosh['name'] = "Hello"
17
+ mosh.name # => "Hello"
18
+
19
+ #it recursively creates moshes from arrays and nested hashes/moshes
20
+ nested = Mosh.new :a => [1, 2, 3], :b => {:c => 2}
21
+ nested.a # => [1, 2, 3]
22
+ nested.b.c # => 2
23
+
24
+ #See more info at the specs diretory.
25
+ == INSTALL:
26
+
27
+ Gem:
28
+
29
+ Mosh is hosted on the GitHub gem repository, so if you haven't already:
30
+
31
+ gem sources -a http://gems.github.com/
32
+ sudo gem install dlt-Mosh
33
+
34
+ Git:
35
+
36
+ git clone git://github.com/dlt/Mosh.git
37
+
38
+ == RESOURCES
39
+
40
+ If you encounter any problems or have ideas for new features
41
+ please send and e-mail to daltojr [] gmail [] com
42
+
43
+
44
+ == LICENSE:
45
+
46
+ Copyright (c) 2009 Dalto Curvelano Jr (http://daltojr.wordpress.com/),
47
+ released under the MIT license
48
+
49
+ Permission is hereby granted, free of charge, to any person obtaining
50
+ a copy of this software and associated documentation files (the
51
+ 'Software'), to deal in the Software without restriction, including
52
+ without limitation the rights to use, copy, modify, merge, publish,
53
+ distribute, sublicense, and/or sell copies of the Software, and to
54
+ permit persons to whom the Software is furnished to do so, subject to
55
+ the following conditions:
56
+
57
+ The above copyright notice and this permission notice shall be
58
+ included in all copies or substantial portions of the Software.
59
+
60
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
61
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
62
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
63
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
64
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
65
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
66
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "mosh"
3
+ s.summary = "A hash extended with methods for easy access to values. Inspired by Mash."
4
+ s.description = "A hash extended with methods for easy access to values. Inspired by Mash."
5
+ s.version = "0.2.1"
6
+ s.date = "2009-03-07"
7
+ s.email = "daltojr@gmail.com"
8
+ s.homepage = "http://github.com/dlt/Mosh"
9
+ s.has_rdoc = false
10
+ s.authors = ["Dalto Curvelano Jr"]
11
+ s.files = ["README", "mosh.gemspec", "mosh.rb", "specs/mosh_spec.rb"]
12
+ end
data/mosh.rb ADDED
@@ -0,0 +1,94 @@
1
+ class Mosh < Hash
2
+
3
+ def initialize(arg = {})
4
+ copy_values arg
5
+ add_hash_methods(arg, '', true)
6
+ end
7
+
8
+ def []=(key, value)
9
+ key = convert_key key
10
+ value = convert_value value
11
+ add_method(key, self)
12
+ super
13
+ end
14
+
15
+ def [](key)
16
+ key = convert_key key
17
+ super
18
+ end
19
+
20
+ private
21
+ def convert_key(key); key.to_s; end
22
+
23
+ def convert_value(value)
24
+ case value
25
+ when Hash
26
+ Mosh.new(value)
27
+ when Array
28
+ value.each_with_index {|item, idx| value[idx] = Mosh.new item if item.is_a? Hash}
29
+ else
30
+ value
31
+ end
32
+ end
33
+
34
+ def extract_method_names(hash, prefix = '')
35
+ hash.each_pair.inject([]) do |arr, (key, value)|
36
+
37
+ method_name = prefix + key.to_s
38
+ arr << method_name
39
+
40
+ case value
41
+ when Hash
42
+ arr << add_hash_methods(value, method_name + '_')
43
+ when Array
44
+ arr << extract_array_method_names(value, method_name + '_') if all_items_are_hashes?(value)
45
+ end
46
+ arr
47
+ end.flatten
48
+ end
49
+
50
+ def add_hash_methods(hash, prefix = '', add_to_self = false)
51
+ meths = extract_method_names(hash, prefix)
52
+ meths.each do |method_name|
53
+ if add_to_self
54
+ add_method(method_name, self)
55
+ else
56
+ add_method(method_name, hash)
57
+ end
58
+ end
59
+ end
60
+
61
+ def extract_array_method_names(array, prefix = '')
62
+ array.collect {|item| add_hash_methods(item, '')}.flatten
63
+ end
64
+
65
+ def add_method(method_name, obj)
66
+ keys = method_name.split '_'
67
+ method = method_string(method_name.gsub(':','_'), keys)
68
+ obj.instance_eval method
69
+ end
70
+
71
+ def all_items_are_hashes?(array)
72
+ array.each do |item|
73
+ return false unless item.is_a? Hash
74
+ end
75
+ true
76
+ end
77
+
78
+ def method_string(method_name, keys)
79
+ hash_accessor = hash_keys_as_string(keys)
80
+ %Q{
81
+ def #{method_name}
82
+ self#{hash_accessor}
83
+ end
84
+ }
85
+ end
86
+
87
+ def hash_keys_as_string(keys)
88
+ keys.map {|k| "['#{k}']"}.join
89
+ end
90
+
91
+ def copy_values(other)
92
+ other.each_pair{|key, value| self[key] = value}
93
+ end
94
+ end
@@ -0,0 +1,65 @@
1
+ require '../mosh.rb'
2
+
3
+ describe Mosh do
4
+ before do
5
+ @mosh = Mosh.new({
6
+ 'rss' => 'items',
7
+ 'links' => ['www.google.com', 'www.google.com.br', 'a string'],
8
+ 'category' => {'a' => 1},
9
+ 'array' => [{'arr:item' => 2}]
10
+ })
11
+ end
12
+
13
+ it "should inherit from hash" do
14
+ @mosh.is_a?(Hash).should be_true
15
+ end
16
+
17
+ it "should have metaprogrammed methods to get hash values" do
18
+ @mosh.rss.should == 'items'
19
+
20
+ @mosh.links.should include('a string')
21
+ @mosh.category.keys.should include('a')
22
+ @mosh.category.keys.should_not include('b')
23
+
24
+ @mosh.category_a.should == 1
25
+ @mosh.category_a.should == @mosh.category['a']
26
+ @mosh.array.first.arr_item.should == 2
27
+ end
28
+
29
+ it "should be able to retrieve hash values through method= calls" do
30
+ @mosh["test"]= "abc"
31
+ @mosh.test.should == "abc"
32
+ @mosh[:taste] = "mint"
33
+ @mosh[:taste].should == "mint"
34
+ @mosh.taste.should == "mint"
35
+ end
36
+
37
+ it "should convert hash assignments into moshes" do
38
+ @mosh['details'] = {:email => 'dalto@asf.com', :address => {:state => 'TX'} }
39
+ @mosh.details.email.should == 'dalto@asf.com'
40
+ @mosh.details.address.state.should == 'TX'
41
+ end
42
+
43
+ it "should convert hashes recursively into moshes" do
44
+ converted = Mosh.new({:a => {:b => 1, :c => {:d => 23}}})
45
+ converted.a.is_a?(Mosh).should be_true
46
+ converted.a.b.should == 1
47
+ converted.a.c.d.should == 23
48
+ end
49
+
50
+ it "should convert hashes in arrays into moshes" do
51
+ converted = Mosh.new({:a => [{:b => 12}, 23]})
52
+ converted.a.first.b.should == 12
53
+ converted.a.last.should == 23
54
+ end
55
+
56
+ it "should convert an existing Mosh into a Mosh" do
57
+ initial = Mosh.new(:name => 'randy', :address => {:state => 'TX'})
58
+ copy = Mosh.new(initial)
59
+ initial.name.should == copy.name
60
+ initial.object_id.should_not == copy.object_id
61
+ copy.address.state.should == 'TX'
62
+ initial.address.state.should == 'TX'
63
+ copy.address.object_id.should_not == initial.address.object_id
64
+ end
65
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dlt-mosh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Dalto Curvelano Jr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-07 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A hash extended with methods for easy access to values. Inspired by Mash.
17
+ email: daltojr@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - mosh.gemspec
27
+ - mosh.rb
28
+ - specs/mosh_spec.rb
29
+ has_rdoc: false
30
+ homepage: http://github.com/dlt/Mosh
31
+ licenses:
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.3.5
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: A hash extended with methods for easy access to values. Inspired by Mash.
56
+ test_files: []
57
+