remi-indifferent-variable-hash 0.1.0

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.markdown ADDED
@@ -0,0 +1,69 @@
1
+ Indifferent Variable Hash
2
+ =========================
3
+
4
+ This tiny library / gem could likely use a new name as "Indifferent Hash"
5
+ can mean a number of things.
6
+
7
+ Here's what this let's you do:
8
+
9
+ $ sudo gem install remi-indifferent-variable-hash -s http://gems.github.com
10
+ $ irb
11
+
12
+ >> require 'rubygems'
13
+ >> require 'indifferent-variable-hash'
14
+
15
+ # extend a class with IndifferentVariableHash
16
+
17
+ >> class Dog
18
+ extend IndifferentVariableHash
19
+ end
20
+
21
+ >> Dog.foo = 'bar'
22
+ => "bar"
23
+
24
+ >> Dog.foo
25
+ => "bar"
26
+
27
+ >> Dog.variables
28
+ => {"foo"=>"bar"}
29
+
30
+ >> Dog['foo']
31
+ => "bar"
32
+
33
+ >> Dog.new.foo
34
+ NoMethodError: undefined method `foo' for #<Dog:0x7f37c87d87d0>
35
+ from (irb):8
36
+ from :0
37
+
38
+ # include IndifferentVariableHash in a class, for instances
39
+
40
+ >> class Dog
41
+ include IndifferentVariableHash
42
+ end
43
+
44
+ >> Dog.new.foo
45
+ => nil
46
+
47
+ >> rover = Dog.new
48
+ => #<Dog:0x7f37c87bfe38>
49
+
50
+ >> rover.foo = 'bar'
51
+ => "bar"
52
+
53
+ >> rover.foo
54
+ => "bar"
55
+
56
+ >> rover[:foo]
57
+ => "bar"
58
+
59
+ >> rover.variables
60
+ => {"foo"=>"bar"}
61
+
62
+ ... why?
63
+ --------
64
+
65
+ Why not! I often add functionality similar to this to some classes that hold config-like information. eg. MyApp.config might return an object that includes IndifferentVariableHash so I can say `MyApp.config.foo = 'bar'` or `MyApp.config[:foo] = 'bar'`. Alternatively, I might like the syntax `MyApp.foo = 'bar'` or `MyApp[:foo] = 'bar'` ... *OR* I might want both syntaxes, so I extend MyApp with IndifferentVariableHash but I also alias 'config' to 'variables.'
66
+
67
+ I use this often enough that I figured I should gem-ify it so I can easily use it in some of my projects, when I want it.
68
+
69
+ If it helps anyone else out there, so be it! Enjoy :)
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+ require 'rake/rdoctask'
4
+ require 'spec/rake/spectask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |s|
9
+ s.name = "indifferent-variable-hash"
10
+ s.summary = "easily add hash-like features to any class / instance"
11
+ s.email = "remi@remitaylor.com"
12
+ s.homepage = "http://github.com/remi/indifferent-variable-hash"
13
+ s.description = "easily add hash-like features to any class / instance"
14
+ s.authors = %w( remi )
15
+ s.files = FileList["[A-Z]*", "{lib,spec,examples,rails_generators}/**/*"]
16
+ # s.executables = "foo"
17
+ # s.add_dependency 'person-project'
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
21
+ end
22
+
23
+ Spec::Rake::SpecTask.new do |t|
24
+ t.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ desc "Run all examples with RCov"
28
+ Spec::Rake::SpecTask.new('rcov') do |t|
29
+ t.spec_files = FileList['spec/**/*_spec.rb']
30
+ t.rcov = true
31
+ end
32
+
33
+ Rake::RDocTask.new do |rdoc|
34
+ rdoc.rdoc_dir = 'rdoc'
35
+ rdoc.title = 'indifferent-variable-hash'
36
+ rdoc.options << '--line-numbers' << '--inline-source'
37
+ rdoc.rdoc_files.include('RDOC_README.rdoc')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
40
+
41
+ desc 'Confirm that gemspec is $SAFE'
42
+ task :safe do
43
+ require 'yaml'
44
+ require 'rubygems/specification'
45
+ data = File.read('indifferent-variable-hash.gemspec')
46
+ spec = nil
47
+ if data !~ %r{!ruby/object:Gem::Specification}
48
+ Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
49
+ else
50
+ spec = YAML.load(data)
51
+ end
52
+ spec.validate
53
+ puts spec
54
+ puts "OK"
55
+ end
56
+
57
+ task :default => :spec
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 1
@@ -0,0 +1,49 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ module IndifferentVariableHash
4
+ attr_accessor :variables
5
+
6
+ def variables
7
+ @variables ||= IndifferentVariableHash::Hash.new
8
+ end
9
+
10
+ def method_missing name, *args
11
+ begin
12
+ self.variables.send name, *args
13
+ rescue Exception => ex
14
+ super
15
+ end
16
+ end
17
+
18
+ # IndifferentVariableHash::Hash extends Hash to be 'indifferent'
19
+ #
20
+ # 'Indifferent' has a few different meanings and needs to be better defined.
21
+ #
22
+ # This is custom in 2 major ways:
23
+ # * All keys will be stringified (so foo[:hi] and foo['hi'] are the same)
24
+ # * Sending messages are translated into keys, eg. foo.hi returns foo['hi']
25
+ #
26
+ class Hash < ::Hash
27
+
28
+ def []= key, value
29
+ super key.to_s, value
30
+ end
31
+
32
+ def [] key
33
+ super key.to_s
34
+ end
35
+
36
+ def method_missing name, *args
37
+ if name.to_s =~ /=$/ # eg. @hash.foo = 'bar'
38
+ self[$`.to_s] = args.first
39
+ else
40
+ if args.empty?
41
+ self[name.to_s] # eg. @hash.foo
42
+ else
43
+ super # anything else ... fall back to super
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,91 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe IndifferentVariableHash do
4
+
5
+ it "obviously, classes and instances shouldn't have these features without including IndifferentVariableHash" do
6
+ klass = Class.new
7
+ instance = klass.new
8
+
9
+ lambda { instance.variables }.should raise_error(NoMethodError, /undefined method `variables'/)
10
+ lambda { instance.foo }.should raise_error(NoMethodError, /undefined method `foo'/)
11
+
12
+ lambda { klass.variables }.should raise_error(NoMethodError, /undefined method `variables'/)
13
+ lambda { klass.foo }.should raise_error(NoMethodError, /undefined method `foo'/)
14
+ end
15
+
16
+ it 'should add a in indifferent hash of variables to instances of a class' do
17
+ klass = Class.new { include IndifferentVariableHash }
18
+ instance = klass.new
19
+
20
+ instance.variables.should be_a_kind_of(Hash)
21
+ instance.foo.should be_nil
22
+ instance.foo = 'Hello There'
23
+ instance.foo.should == 'Hello There'
24
+
25
+ # klass should *not* have variables, just instances
26
+ lambda { klass.variables }.should raise_error(NoMethodError, /undefined method `variables'/)
27
+ end
28
+
29
+ it 'should add a in indifferent hash of variables to a class' do
30
+ klass = Class.new { extend IndifferentVariableHash }
31
+ instance = klass.new
32
+
33
+ klass.variables.should be_a_kind_of(Hash)
34
+ klass.foo.should be_nil
35
+ klass.foo = 'Hello There'
36
+ klass.foo.should == 'Hello There'
37
+
38
+ # instance should *not* have variables, just instances
39
+ lambda { instance.variables }.should raise_error(NoMethodError, /undefined method `variables'/)
40
+ end
41
+
42
+ it 'should add a in indifferent hash of variables to a class and instances of the same class' do
43
+ klass = Class.new { extend IndifferentVariableHash; include IndifferentVariableHash }
44
+ instance = klass.new
45
+
46
+ [ klass, instance ].each do |obj|
47
+ obj.variables.should be_a_kind_of(Hash)
48
+ obj.foo.should be_nil
49
+ obj.foo = 'Hello There'
50
+ obj.foo.should == 'Hello There'
51
+ end
52
+ end
53
+
54
+ it 'should be easy[-ish] to give your own custom name for the hash variable' do
55
+ klass = Class.new { extend IndifferentVariableHash }
56
+ klass.foo = 'Hello There'
57
+
58
+ klass.foo.should == 'Hello There'
59
+ klass.variables.foo.should == 'Hello There'
60
+
61
+ klass.instance_eval { alias config variables } # just add an alias! nothing custom needed to do this.
62
+ klass.config.foo.should == 'Hello There'
63
+ klass.config['foo'].should == 'Hello There'
64
+ klass.config[:foo].should == 'Hello There'
65
+ end
66
+
67
+ it 'should not make *all* Hashes indifferent' do
68
+ custom_hash = IndifferentVariableHash::Hash.new
69
+ custom_hash.foo.should be_nil
70
+ custom_hash.foo = 'bar'
71
+ custom_hash.foo.should == 'bar'
72
+
73
+ regular_hash = Hash.new
74
+ lambda { regular_hash.foo }.should raise_error(NoMethodError, /undefined method `foo'/)
75
+ end
76
+
77
+ it "should really be 'indifferent' (shouldn't matter whether a string or a symbol is used)" do
78
+ custom_hash = IndifferentVariableHash::Hash.new
79
+
80
+ custom_hash.foo = 'bar'
81
+ custom_hash.foo.should == 'bar'
82
+ custom_hash['foo'].should == 'bar'
83
+ custom_hash[:foo].should == 'bar'
84
+
85
+ custom_hash[:foo] = 'BAR'
86
+ custom_hash.foo.should == 'BAR'
87
+ custom_hash['foo'].should == 'BAR'
88
+ custom_hash[:foo].should == 'BAR'
89
+ end
90
+
91
+ end
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/../lib/indifferent-variable-hash'
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remi-indifferent-variable-hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - remi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-03 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: easily add hash-like features to any class / instance
17
+ email: remi@remitaylor.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - VERSION.yml
27
+ - README.markdown
28
+ - lib/indifferent-variable-hash.rb
29
+ - spec/indifferent_variable_hash_spec.rb
30
+ - spec/spec_helper.rb
31
+ has_rdoc: true
32
+ homepage: http://github.com/remi/indifferent-variable-hash
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --inline-source
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: easily add hash-like features to any class / instance
58
+ test_files: []
59
+