hashpipe 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Erik Hollensbe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ = HashPipe -- hash-alike openstructs for ruby.
2
+
3
+ Come on and kick me.
4
+ You’ve got your problems;
5
+ I’ve got my ass wide
6
+ You’ve got your big G's;
7
+ I’ve got my hash pipe.
8
+
9
+ - Weezer, /Hash Pipe/
10
+
11
+ HashPipe is a library to supplement users of OpenStruct and similar libs. It
12
+ operates leak free at insertion cost and optimizes for the common case:
13
+ reading, like a good hash table should. HashPipe includes Enumerable and a
14
+ basic keys/values implementation.
15
+
16
+ HashPipe also contains a locking mechanism whereby you can eliminate the
17
+ ability to add more items, similar to Object#freeze in a sense.
18
+
19
+ Examples:
20
+
21
+ h = HashPipe.new
22
+ h[:foo] = "bar"
23
+ h.foo #=> "bar"
24
+ h["bar"] = "quux"
25
+ h[:bar] #=> "quux"
26
+ h.bar #=> "quux"
27
+
28
+ h.lock! # no new attributes can be created
29
+
30
+ h.quux # raises
31
+ h[:quux] # raises
32
+ h['quux'] # raises
33
+ h.foo #=> "bar"
34
+
35
+ h.keys #=> [:foo, :bar]
36
+ h.values #=> ["bar", "quux"]
37
+
38
+ h.map { |k,v| [k,v] } #=> [[:foo, "bar"], [:bar, "quux"]]
39
+
40
+ == Note on Patches/Pull Requests
41
+
42
+ * Fork the project.
43
+ * Make your feature addition or bug fix.
44
+ * Add tests for it. This is important so I don't break it in a
45
+ future version unintentionally.
46
+ * Commit, do not mess with rakefile, version, or history.
47
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
48
+ * Send me a pull request. Bonus points for topic branches.
49
+
50
+ == Copyright
51
+
52
+ Copyright (c) 2010 Erik Hollensbe. See LICENSE for details.
@@ -0,0 +1,59 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "hashpipe"
8
+ gem.summary = %Q{Create openstructs that are also symbol and string structs!}
9
+ gem.description = %Q{Create openstructs that are also symbol and string structs! Lock them! Index them! You've got your problems, I've got your hash pipe.}
10
+ gem.email = "erik@hollensbe.org"
11
+ gem.homepage = "http://github.com/erikh/hashpipe"
12
+ gem.authors = ["Erik Hollensbe"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ gem.add_development_dependency 'test-unit'
15
+ gem.add_development_dependency 'rdoc'
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rdoc/task'
47
+ RDoc::Task.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.main = "README.rdoc"
52
+ rdoc.title = "HashPipe #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
56
+
57
+ task :to_blog => [:clobber_rdoc, :rdoc] do
58
+ sh "rm -fr $git/blog/content/docs/hashpipe && mv rdoc $git/blog/content/docs/hashpipe"
59
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,99 @@
1
+ #
2
+ # HashPipe is a library to supplement users of OpenStruct and similar libs. It
3
+ # operates leak free at insertion cost and optimizes for the common case:
4
+ # reading, like a good hash table should. HashPipe includes Enumerable and a
5
+ # basic keys/values implementation.
6
+ #
7
+ # HashPipe also contains a locking mechanism whereby you can eliminate the
8
+ # ability to add more items, similar to Object#freeze in a sense.
9
+ #
10
+ # Examples:
11
+ #
12
+ # h = HashPipe.new
13
+ # h[:foo] = "bar"
14
+ # h.foo #=> "bar"
15
+ # h["bar"] = "quux"
16
+ # h[:bar] #=> "quux"
17
+ # h.bar #=> "quux"
18
+ #
19
+ # h.lock! # no new attributes can be created
20
+ #
21
+ # h.quux # raises
22
+ # h[:quux] # raises
23
+ # h['quux'] # raises
24
+ # h.foo #=> "bar"
25
+ #
26
+ # h.keys #=> [:foo, :bar]
27
+ # h.values #=> ["bar", "quux"]
28
+ #
29
+ # h.map { |k,v| [k,v] } #=> [[:foo, "bar"], [:bar, "quux"]]
30
+ #
31
+ class HashPipe
32
+ def self.create_accessor(sym, obj)
33
+ unless obj.__respond_to?(sym)
34
+ class << obj; self; end.attr_accessor(sym)
35
+ end
36
+ end
37
+
38
+ if :foo.respond_to?(:[]) # ruby1.9 optimization
39
+ def self.callable_ivar(ivar)
40
+ ivar[/^@?(.*)$/, 1].to_sym
41
+ end
42
+ else
43
+ def self.callable_ivar(ivar)
44
+ ivar.to_s[/^@?(.*)$/, 1].to_sym
45
+ end
46
+ end
47
+
48
+ class << self
49
+ public :attr_accessor
50
+ end
51
+
52
+ alias __class__ class unless defined?(__class__) # rbx has it.
53
+ alias __instance_variables__ instance_variables
54
+ alias __respond_to? respond_to?
55
+ instance_methods.each { |m| undef_method m unless m =~ /^__|\?$/ }
56
+
57
+ include Enumerable
58
+
59
+ def [](sym_or_str)
60
+ self.__class__.create_accessor(sym_or_str, self)
61
+ self.__send__(sym_or_str)
62
+ end
63
+
64
+ def []=(sym_or_str, value)
65
+ self.__class__.create_accessor(sym_or_str, self)
66
+ self.__send__(:"#{sym_or_str}=", value)
67
+ end
68
+
69
+ def method_missing(sym, *args)
70
+ newsym = sym.to_s.gsub(/=$/, '').to_sym
71
+ if __respond_to?(newsym)
72
+ raise ArgumentError, "#{newsym} cannot be defined on #{self.inspect}"
73
+ else
74
+ self.__class__.create_accessor(newsym, self)
75
+ self.__send__(sym, *args)
76
+ end
77
+ end
78
+
79
+ def keys
80
+ __instance_variables__.map { |ivar| self.__class__.callable_ivar(ivar) }
81
+ end
82
+
83
+ def values
84
+ __instance_variables__.map { |ivar|
85
+ self.__send__(self.__class__.callable_ivar(ivar))
86
+ }
87
+ end
88
+
89
+ def each
90
+ __instance_variables__.each do |ivar|
91
+ callable = self.__class__.callable_ivar(ivar)
92
+ yield(callable, self.__send__(callable))
93
+ end
94
+ end
95
+
96
+ def lock!
97
+ class << self; undef_method :method_missing; end
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ gem 'test-unit'
3
+ require 'test/unit'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'hashpipe'
8
+
9
+ class Test::Unit::TestCase
10
+ def create_sos
11
+ HashPipe.new
12
+ end
13
+ end
@@ -0,0 +1,86 @@
1
+ require 'helper'
2
+
3
+ class TestHashpipeSuperOpenStruct < Test::Unit::TestCase
4
+ def test_01_construct
5
+ h = create_sos
6
+ assert(h)
7
+ assert_kind_of(HashPipe, h)
8
+ assert_respond_to(h, :lock!)
9
+ end
10
+
11
+ def test_02_accessors
12
+ h = create_sos
13
+
14
+ h.foo = "bar"
15
+ assert_equal(h.foo, "bar")
16
+ assert_equal(h[:foo], "bar")
17
+ assert_equal(h['foo'], "bar")
18
+
19
+ h.bar = "baz"
20
+ assert_equal(h.bar, "baz")
21
+ assert_equal(h[:bar], "baz")
22
+ assert_equal(h['bar'], "baz")
23
+ end
24
+
25
+ def test_03_lock
26
+ h2 = create_sos
27
+ h = create_sos
28
+
29
+ h.foo = "bar"
30
+ h.lock!
31
+
32
+ assert_raises(NoMethodError) do
33
+ h.bar = "baz"
34
+ end
35
+
36
+ assert_equal(h.foo, "bar")
37
+ assert_equal(h[:foo], "bar")
38
+ assert_equal(h['foo'], "bar")
39
+
40
+ # should not raise
41
+ h2.bar = "baz"
42
+ h2.bar = "baz"
43
+
44
+ assert_equal(h2.bar, "baz")
45
+ assert_equal(h2[:bar], "baz")
46
+ assert_equal(h2['bar'], "baz")
47
+ end
48
+
49
+ def test_04_overwrite
50
+ h = create_sos
51
+ assert_respond_to(h, :map)
52
+
53
+ assert_raises(ArgumentError) { h.map = "foo" }
54
+ assert_raises(ArgumentError) { h[:map] = "foo" }
55
+ assert_raises(ArgumentError) { h['map'] = "foo" }
56
+ end
57
+
58
+ def test_05_keys_values
59
+ h = create_sos
60
+ h.foo = "bar"
61
+ h.bar = "quux"
62
+
63
+ assert_equal(
64
+ h.keys.sort_by { |x| x.to_s },
65
+ [:bar, :foo]
66
+ )
67
+
68
+ assert_equal(
69
+ h.values.sort_by { |x| x.to_s },
70
+ ["bar", "quux"]
71
+ )
72
+ end
73
+
74
+ def test_06_enumerable
75
+ h = create_sos
76
+ assert_respond_to(h, :map)
77
+
78
+ h[:foo] = "bar"
79
+ h.bar = :foo
80
+
81
+ assert_equal(
82
+ h.map { |k,v| [k,v] }.sort_by { |r| r[0].to_s },
83
+ [[:bar, :foo], [:foo, "bar"]]
84
+ )
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashpipe
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Erik Hollensbe
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-07 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: test-unit
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: rdoc
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :development
43
+ version_requirements: *id002
44
+ description: Create openstructs that are also symbol and string structs! Lock them! Index them! You've got your problems, I've got your hash pipe.
45
+ email: erik@hollensbe.org
46
+ executables: []
47
+
48
+ extensions: []
49
+
50
+ extra_rdoc_files:
51
+ - LICENSE
52
+ - README.rdoc
53
+ files:
54
+ - .document
55
+ - .gitignore
56
+ - LICENSE
57
+ - README.rdoc
58
+ - Rakefile
59
+ - VERSION
60
+ - lib/hashpipe.rb
61
+ - test/helper.rb
62
+ - test/test_hashpipe_superopenstruct.rb
63
+ has_rdoc: true
64
+ homepage: http://github.com/erikh/hashpipe
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --charset=UTF-8
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.3.6
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Create openstructs that are also symbol and string structs!
93
+ test_files:
94
+ - test/helper.rb
95
+ - test/test_hashpipe_superopenstruct.rb