colby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,28 @@
1
+ # Colby
2
+
3
+ Experimenting with bringing Clojure's goodness in Ruby.
4
+
5
+ - This project depends on [Hamster](https://github.com/harukizaemon/hamster)
6
+ - The basic idea for now is to have something broadly equivalent to [Mori](http://swannodette.github.com/mori/), but in Ruby
7
+
8
+ ## Testing
9
+
10
+ - `rspec .`
11
+
12
+ ## Usage
13
+
14
+ - make sure you have 1.9.3-p194
15
+ - `bundle install`
16
+
17
+ ```ruby
18
+ require './colby.rb'
19
+
20
+ include Colby::Core
21
+
22
+ # Now you can build hash_map, vec, list, or set
23
+
24
+ # Also, you have clojure-like functions such as assoc, get, conj, has_key
25
+
26
+ # check the spec to see examples
27
+
28
+ ```
@@ -0,0 +1,23 @@
1
+ $: << "#{File.dirname(__FILE__)}/lib"
2
+ require 'colby'
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Gursimran Singh"]
6
+ gem.email = ["g@kilotau.com"]
7
+ gem.description = %q{Small wrapper and functions for persistent, immutable data structures.}
8
+ gem.summary = %q{Colby makes it easier to work with persistent, immutable data structures.
9
+ It wraps Hamster's excellent data structures and provides functions to work
10
+ with them that are similar to Clojure, but not exactly.}
11
+ gem.homepage = "http://github.com/gnarmis/colby"
12
+
13
+ gem.add_development_dependency('rake')
14
+ gem.add_development_dependency('rspec')
15
+
16
+ gem.add_dependency('hamster')
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map {|f| File.basename(f)}
20
+ gem.name = "colby"
21
+ gem.require_paths = ["lib"]
22
+ gem.version = Colby::VERSION
23
+ end
@@ -0,0 +1,3 @@
1
+ require 'colby/core'
2
+ require 'colby/version'
3
+
@@ -0,0 +1,114 @@
1
+ require 'hamster'
2
+
3
+ class IndexOutOfBounds < Exception; end
4
+
5
+ module Colby
6
+ module Core
7
+
8
+ def hash_map(*pairs)
9
+ return Hamster.hash(Hash[*pairs]) if pairs.is_a? Array
10
+ return Hamster.hash(*pairs) if pairs.is_a? Hash
11
+ end
12
+
13
+ def vec(*data)
14
+ Hamster.vector(*data)
15
+ end
16
+
17
+ def list(*data)
18
+ Hamster.list(*data)
19
+ end
20
+
21
+ def set(*data)
22
+ Hamster.set(*data)
23
+ end
24
+
25
+ def conj(coll, item)
26
+ return coll.cons(item) if coll.is_a? Hamster::List
27
+ return coll.add(item) if coll.is_a? Hamster::Vector
28
+ return coll.merge(item) if coll.is_a? Hamster::Hash
29
+ return Hamster.set(*coll, item) if coll.is_a? Hamster::Set
30
+ end
31
+
32
+ def assoc(coll, *pairs)
33
+ @retval = coll
34
+ pairs.each_slice(2) do |k,v|
35
+ @retval = assoc_2(@retval, k , v)
36
+ end
37
+ @retval
38
+ end
39
+
40
+ def assoc_2(coll, key, val)
41
+ if coll.is_a? Hamster::Hash
42
+ return coll.send(:put, key) {val}
43
+ end
44
+ if coll.is_a? Hamster::Vector
45
+ if has_key(coll, key)
46
+ return coll.send(:set, key, val)
47
+ else
48
+ raise IndexOutOfBounds
49
+ end
50
+ end
51
+ end
52
+
53
+ def get(coll, key)
54
+ coll.get(key) unless coll.is_a? Hamster::List
55
+ end
56
+
57
+ def nth(coll, key)
58
+ return get(coll, key) if coll.is_a? Hamster::Vector
59
+ return coll.to_a[key] if coll.is_a? Hamster::List
60
+ end
61
+
62
+ def find(coll, key)
63
+ return Core.vec(key, Core.get(coll, key)) if coll.is_a? Hamster::Vector
64
+ return Core.vec(key, Core.get(coll,key)) if coll.is_a? Hamster::Hash
65
+ end
66
+
67
+ def has_key(coll, key)
68
+ return coll.has_key?(key) if coll.is_a? Hamster::Hash
69
+ return coll[key] != nil if (coll.is_a? Hamster::Vector) || (coll.is_a? Hamster::Set)
70
+ nil
71
+ end
72
+
73
+ def count(coll)
74
+ return coll.length
75
+ end
76
+
77
+ def peek(coll)
78
+ return coll.head if coll.is_a? Hamster::List
79
+ return coll.last if coll.is_a? Hamster::Vector
80
+ end
81
+
82
+ def pop(coll)
83
+ return coll.tail if coll.is_a? Hamster::List
84
+ if coll.is_a? Hamster::Vector
85
+ return vec(*coll.to_a[0..-2])
86
+ end
87
+ end
88
+
89
+ def zip_map(coll1, coll2)
90
+ return hash_map(Hash[coll1.to_a.zip(coll2.to_a)])
91
+ end
92
+
93
+ def seq(data)
94
+ if data.is_a? Hamster::List
95
+ return data
96
+ elsif data.is_a? Array or data.is_a? Hamster::Vector
97
+ return list(*data)
98
+ elsif data.is_a? Hash
99
+ return list(*data.keys.to_a.zip(data.values.to_a))
100
+ elsif data.is_a? Hamster::Hash
101
+ l = list
102
+ data.foreach {|k,v| l = conj(l,(list k, v))}
103
+ return l
104
+ elsif data.is_a? Hamster::Set
105
+ return (list(*data)).sort
106
+ elsif data.is_a? String
107
+ return list(*data.split(""))
108
+ else
109
+ raise Exception
110
+ end
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,3 @@
1
+ module Colby
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,148 @@
1
+ $: << "#{File.dirname(__FILE__)}/../lib"
2
+
3
+ require 'colby'
4
+
5
+ include Colby::Core
6
+
7
+ describe "Colby" do
8
+
9
+ describe "Core" do
10
+
11
+ it "should construct hash-maps given a Ruby Hash" do
12
+ hash_map(:a => 1).should == Hamster.hash(:a => 1)
13
+ end
14
+ it "should construct vectors given values" do
15
+ vec(1,2,3).should == Hamster.vector(1,2,3)
16
+ end
17
+ it "should construct lists given values" do
18
+ list(1,2,3).should == Hamster.list(1,2,3)
19
+ end
20
+ it "should construct sets given values" do
21
+ set(1,2,3,3).should == Hamster.set(1,2,3,3)
22
+ end
23
+
24
+ it "should conj items to head of list" do
25
+ conj(list(1,2,3), 0).should == list(0,1,2,3)
26
+ end
27
+ it "should conj items to end of vector" do
28
+ conj(vec(1,2,3), 0).should == vec(1,2,3,0)
29
+ end
30
+ it "should conj hash_maps by merging them" do
31
+ conj(hash_map(:a=>1),
32
+ hash_map(:b=>2,:c=>3)).should == hash_map(:a=>1,:b=>2,:c=>3)
33
+ end
34
+ it "should assoc new key-value pairs when conj'ing hash_maps" do
35
+ conj(hash_map(:a=>1),
36
+ hash_map(:a=>2,:c=>3)).should == hash_map(:a=>2,:c=>3)
37
+ end
38
+ it "should conj sets by making a bigger set" do
39
+ conj(set(1,2,3,3), 4).should == set(1,2,3,4)
40
+ end
41
+
42
+
43
+ it "should assoc any number of pairs into a hash_map collection" do
44
+ assoc(hash_map(:a=>1),
45
+ :a, 2,
46
+ :b, 3,
47
+ :c, 4).should == hash_map(:a=>2,
48
+ :b=>3,
49
+ :c=>4)
50
+ end
51
+ it "should assoc index-bounded pairs into a vector collection" do
52
+ assoc(vec(1,2,3),0,4,1,5,2,6).should == vec(4,5,6)
53
+ end
54
+ it "should raise an exception if unbounded pairs used to assoc into a vec" do
55
+ expect {assoc(vec(1,2),9,9)}.to raise_error
56
+ end
57
+
58
+
59
+ it "should return value when using get with a hash_map" do
60
+ get( hash_map(:a=>1), :a).should == 1
61
+ end
62
+ it "should return value when using get with a vector" do
63
+ get( vec(1,2), 0).should == 1
64
+ end
65
+
66
+
67
+ it "should return value when using nth with a vec" do
68
+ nth(vec(1,2,3), 0).should == 1
69
+ end
70
+ it "should return value when using nth with a list" do
71
+ nth(list(1,2,3), 0).should == 1
72
+ end
73
+ it "should not return value when using nth with a set" do
74
+ nth(set(1,2,3), 0).should_not == 1
75
+ end
76
+ it "should not return value when using nth with a hash_map" do
77
+ nth(hash_map(1,2,3,4), 1).should_not == 2
78
+ end
79
+
80
+
81
+
82
+ it "should return key/val pair as a vector for a vector" do
83
+ find(vec(1,2),0).should == vec(0,1)
84
+ end
85
+ it "should return key/val pair as a vector for a hash_map" do
86
+ find(hash_map(1,2,3,4), 3).should == vec(3,4)
87
+ end
88
+
89
+
90
+ it "should return bool if vec has or doesn't have key" do
91
+ has_key(vec(1,2), 0).should == true
92
+ has_key(vec(1,2), 3).should == false
93
+ end
94
+ it "should return bool if hash_map has or doesn't have key" do
95
+ has_key(hash_map(:a=>1), :a).should == true
96
+ has_key(hash_map(:a=>1), 3).should == false
97
+ end
98
+
99
+
100
+ it "should return count for lists" do
101
+ count(list(1,2,3)).should == 3
102
+ end
103
+ it "should return count for vectors" do
104
+ count(vec(1,2,3)).should == 3
105
+ end
106
+ it "should return count for sets" do
107
+ count(set(1,2,3)).should == 3
108
+ end
109
+ it "should return count for hash_maps" do
110
+ count(hash_map(1=>2,3=>4)).should == 2
111
+ end
112
+
113
+
114
+ it "should return head of list when using peek" do
115
+ peek(list(1,2,3)).should == 1
116
+ end
117
+ it "should return last element of vec when using peek" do
118
+ peek(vec(1,2,3)).should == 3
119
+ end
120
+
121
+
122
+ it "should return list with head removed when using pop" do
123
+ pop(list(1,2,3)).should == list(2,3)
124
+ end
125
+ it "should return vec with last item removed when using pop" do
126
+ pop(vec(1,2,3)).should == vec(1,2)
127
+ end
128
+
129
+
130
+ it "should zip two seqs into a hash_map" do
131
+ zip_map(vec(1,2,3), list(4,5,6)).should == hash_map(1,4,2,5,3,6)
132
+ end
133
+
134
+
135
+ it "should convert Arrays, lists, and vecs into a seq (list)" do
136
+ seq([1,2,4,3]).should == list(1,2,4,3)
137
+ seq(list(1,2,4,3)).should == list(1,2,4,3)
138
+ seq(vec(1,2,4,3)).should == list(1,2,4,3)
139
+ end
140
+ it "should convert a Hash into a seq" do
141
+ seq(hash_map(:a,2)).should == list(list(:a,2))
142
+ end
143
+ it "should convert a String into a seq" do
144
+ seq("abc").should == list("a","b","c")
145
+ end
146
+ end
147
+
148
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: colby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gursimran Singh
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: hamster
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Small wrapper and functions for persistent, immutable data structures.
63
+ email:
64
+ - g@kilotau.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - README.md
72
+ - colby.gemspec
73
+ - lib/colby.rb
74
+ - lib/colby/core.rb
75
+ - lib/colby/version.rb
76
+ - spec/core_spec.rb
77
+ homepage: http://github.com/gnarmis/colby
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.24
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Colby makes it easier to work with persistent, immutable data structures.
101
+ It wraps Hamster's excellent data structures and provides functions to work with
102
+ them that are similar to Clojure, but not exactly.
103
+ test_files: []