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 +69 -0
- data/Rakefile +57 -0
- data/VERSION.yml +4 -0
- data/lib/indifferent-variable-hash.rb +49 -0
- data/spec/indifferent_variable_hash_spec.rb +91 -0
- data/spec/spec_helper.rb +1 -0
- metadata +59 -0
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,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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
+
|