duplo 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ced13192f8a77859809d3f5152405b8b8277d422
4
- data.tar.gz: 82096e9fd70ffb4a938ace1f83cf69bbd5a1cd38
3
+ metadata.gz: 0d02593bee25e38b9368df7f965717035db59579
4
+ data.tar.gz: af814995e2b547a0d85f3ba5cf02b95962b8088b
5
5
  SHA512:
6
- metadata.gz: 81567d7e7c0185dde4fcb4982a56fd09c2fd65093ef0ce0487ec908b8fe2dec9f78210ce81a125e19b31e1139de89b934ff63b34fb147c19c1893d1edadda908
7
- data.tar.gz: 32845ca94f81a928a665353c463320e7ac991c4ebe90e00f84f7e30fbb0f882be8f3245c7cf4e293bf9a6689a82f73dfe8035bafc552b61475ba25be78ed1a21
6
+ metadata.gz: cc9294e2222a29169114d39483d8f624f7507cf0523af3ddbc9961f288ba5331db8107d7101a2cff067ffeca08978f10e8773f2121e0fc94b972ff12e89d76f4
7
+ data.tar.gz: 84bfb768ff5d817cf694b9f7914baa2dc77589f72d0e1232ee9bb9bde8d36355e8669817832ea87937e6cb6182a64ad8d2e22fb35c99c848263385960679e021
@@ -1,5 +1,10 @@
1
1
  # Duplo changelog
2
2
 
3
+ ### 0.1.2 (2015-08-30)
4
+
5
+ * Yield integers for vector entries instead of arrays
6
+ * Drop `#abc`
7
+
3
8
  ### 0.1.1 (2015-05-09)
4
9
 
5
10
  * Provide `#respond_to_missing?`
data/README.md CHANGED
@@ -4,22 +4,16 @@ Duplo
4
4
  [![Gem Version](https://badge.fury.io/rb/duplo.svg)](https://rubygems.org/gems/duplo)
5
5
  [![Build Status](https://travis-ci.org/topalovic/duplo.svg?branch=master)](https://travis-ci.org/topalovic/duplo)
6
6
 
7
- Generate nested collections with minimum effort.
7
+ A tiny Ruby DSL for generating collections.
8
8
 
9
- ```
10
- .-===============-.
11
- | ( ) ( ) ( ) ( ) |
12
- | ( ) ( ) ( ) ( ) |
13
- '-----------------' ndt.
14
- ```
9
+ <img src="https://cloud.githubusercontent.com/assets/626128/7639329/545932e6-fa7b-11e4-84b0-a64c9e23c9df.png" width="100">
15
10
 
16
11
 
17
12
  ## Usage
18
13
 
19
- Let's say you like matrices (bear with me), but not rolling them out
20
- by hand or writing nested loops to populate them. Or you might need a
21
- few nested hashes to test something real quick in the console, but
22
- generating them can be a royal PITA.
14
+ Let's say you like matrices (bear with me) but not rolling them out by
15
+ hand. Or say you need to generate some data samples quickly in the
16
+ console but writing nested loops is not really your idea of fun.
23
17
 
24
18
  So how about this:
25
19
 
@@ -27,126 +21,134 @@ So how about this:
27
21
  require "duplo"
28
22
  include Duplo
29
23
 
30
- a3a4
31
- # => [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
24
+ a4a8
25
+ #=> [[0, 1, 2, 3, 4, 5, 6, 7],
26
+ # [0, 1, 2, 3, 4, 5, 6, 7],
27
+ # [0, 1, 2, 3, 4, 5, 6, 7],
28
+ # [0, 1, 2, 3, 4, 5, 6, 7]]
32
29
  ```
33
30
 
34
- Bam. A 3x4 matrix.
31
+ Bam. A 4x8 matrix.
35
32
 
36
- Want it random? Sure. Pass it a block to populate the entries:
33
+ Want it randomized? Just pass it a block to populate the entries:
37
34
 
38
35
  ```ruby
39
- a3a4 { rand -5..5 }
40
- # => [[1, 9, 8, 3], [3, 0, -1, -2], [2, 0, 5, -7]]
41
- a3a4 { rand }
42
- # => [[0.6222777300676433, 0.5613390139342668, 0.37293736375203324, 0.7319666374054961],
43
- # [0.3798588109025701, 0.33483069318178915, 0.8779112502970073, 0.22476545143154103],
44
- # [0.37651300630626683, 0.5035024403835663, 0.8237420938739567, 0.7611012983149591]]
36
+ a4a8 { rand 10 }
37
+ #=> [[5, 1, 2, 7, 8, 9, 6, 1],
38
+ # [7, 6, 6, 0, 7, 1, 0, 8],
39
+ # [9, 3, 8, 7, 6, 4, 4, 5],
40
+ # [3, 0, 9, 0, 7, 3, 8, 9]]
45
41
  ```
46
42
 
47
- Accessing the current entry path is easy peasy. Have an identity
48
- matrix:
43
+ This works too:
49
44
 
50
45
  ```ruby
51
- I4 = a4a4 { |i, j| i == j ? 1 : 0 }
52
- # => [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
46
+ Duplo.a4a8
53
47
  ```
54
48
 
55
- Have I mentioned that you can go up to an arbitrary number of
56
- dimensions?
49
+ so including the module is optional. The gem works its magic through
50
+ `method_missing` so it won't stomp on existing names either way.
51
+
52
+
53
+ ### Entry path
54
+
55
+ Populating the entries is easy peasy. Here, have an identity matrix:
57
56
 
58
57
  ```ruby
59
- a3a3a2 { |i,j,k| [i,j,k].join(":") }
60
- # => [[["0:0:0", "0:0:1"], ["0:1:0", "0:1:1"], ["0:2:0", "0:2:1"]],
61
- # [["1:0:0", "1:0:1"], ["1:1:0", "1:1:1"], ["1:2:0", "1:2:1"]],
62
- # [["2:0:0", "2:0:1"], ["2:1:0", "2:1:1"], ["2:2:0", "2:2:1"]]]
58
+ I5 = a5a5 { |i, j| i == j ? 1 : 0 }
59
+ #=> [[1, 0, 0, 0, 0],
60
+ # [0, 1, 0, 0, 0],
61
+ # [0, 0, 1, 0, 0],
62
+ # [0, 0, 0, 1, 0],
63
+ # [0, 0, 0, 0, 1]
63
64
  ```
64
65
 
65
- Heads up, it might get a bit sluggish with higher dims due to the
66
- recursive approach under the hood.
67
-
68
- Now how 'bout them Hashes:
66
+ If plain old matrices bore you, you can do simple vectors:
69
67
 
70
68
  ```ruby
71
- h3h2h2 { |path| "I'm a #{path.join}" }
72
- # => {0=>{0=>{0=>"I'm a 000", 1=>"I'm a 001"}, 1=>{0=>"I'm a 010", 1=>"I'm a 011"}},
73
- # 1=>{0=>{0=>"I'm a 100", 1=>"I'm a 101"}, 1=>{0=>"I'm a 110", 1=>"I'm a 111"}},
74
- # 2=>{0=>{0=>"I'm a 200", 1=>"I'm a 201"}, 1=>{0=>"I'm a 210", 1=>"I'm a 211"}}}
69
+ a10 { |i| i ** 2 }
70
+ #=> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
75
71
  ```
76
72
 
77
- You can also use `s` for Sets, and mix and match collection types to
78
- your little heart's desire:
73
+ or arbitrary tensors:
79
74
 
80
75
  ```ruby
81
- ah2s3 { abc.sample(2).join }
82
- # => [{0=>#<Set: {"kx", "by", "fi"}>, 1=>#<Set: {"uz", "ow", "tx"}>},
83
- # {0=>#<Set: {"tp", "ch", "ba"}>, 1=>#<Set: {"nu", "mn", "ve"}>},
84
- # {0=>#<Set: {"nc", "dh", "dc"}>, 1=>#<Set: {"le", "ks", "th"}>},
85
- # {0=>#<Set: {"ca", "xj", "lm"}>, 1=>#<Set: {"hg", "xg", "rz"}>},
86
- # {0=>#<Set: {"oq", "vb", "ed"}>, 1=>#<Set: {"gq", "px", "sv"}>}]
76
+ a4a11a2a3 { |path| path.join(":") }
77
+ #=> [[[["0:0:0:0", "0:0:0:1", "0:0:0:2"],
78
+ # ["0:0:1:0", "0:0:1:1", "0:0:1:2"]],
79
+ # . . .
80
+ # ["3:10:1:0", "3:10:1:1", "3:10:1:2"]]]]
87
81
  ```
88
82
 
89
- You get the picture. If you're *really* bored, you can spell those out
90
- loud:
83
+ The last example also shows how to use the full entry path without
84
+ destructuring.
85
+
86
+
87
+ ### Other toys
88
+
89
+ In addition to `a`rrays, you can build `h`ashes and `s`ets, and mix
90
+ and match collection types to your heart's desire:
91
91
 
92
92
  ```ruby
93
- Duplo.spell "ah2s0"
94
- # => "5-element Array containing 2-element Hashes containing empty Sets"
93
+ sa2h3 { rand 100 }
94
+ #=> #<Set: {[{0=>11, 1=>47, 2=>48}, {0=>3, 1=>71, 2=>57}],
95
+ # [{0=>97, 1=>9, 2=>43}, {0=>90, 1=>30, 2=>62}],
96
+ # [{0=>87, 1=>56, 2=>23}, {0=>24, 1=>16, 2=>63}],
97
+ # [{0=>6, 1=>12, 2=>57}, {0=>44, 1=>3, 2=>74}],
98
+ # [{0=>52, 1=>92, 2=>12}, {0=>93, 1=>32, 2=>1}]}>
95
99
  ```
96
100
 
97
- Note that I've omitted a dim for the root array in that last
98
- example. It defaults to 5, so `as2h` means the same thing as
99
- `a5s2h5`. You can easily change it like this:
101
+ Let's spell that out:
100
102
 
101
103
  ```ruby
102
- Duplo.default_size = 3
104
+ Duplo.spell "sa2h3"
105
+ #=> "5-element Set containing 2-element Arrays containing 3-element Hashes"
103
106
  ```
104
107
 
105
- Also, I sneaked in a cute little `abc` method that returns the
106
- alphabet as an array (as seen in the last example).
108
+ Note that I've omitted size for the root collection there. It defaults
109
+ to 5, so `aaa` yields the same result as `a5a5a5`. Set your preferred
110
+ default like this:
107
111
 
112
+ ```ruby
113
+ Duplo.default_size = 10
114
+ ```
108
115
 
109
- ## Installation
110
116
 
111
- You know the drill.
117
+ ### Dynamic dimensions
112
118
 
113
- Add this line to your application's Gemfile, presumably in the
114
- "development" or "test" group:
119
+ If you want to supply dimensions dynamically, this should do the trick:
115
120
 
116
121
  ```ruby
117
- gem "duplo"
122
+ m, n = 3, 4
123
+ toy = "a#{m}a#{n}"
124
+
125
+ Duplo.build(toy) { rand }
118
126
  ```
119
127
 
120
- or install it yourself as:
121
128
 
122
- ```console
123
- $ gem install duplo
124
- ```
129
+ ## Installation
125
130
 
126
- It's not really necessary to include the module, you can use it
127
- directly:
131
+ Add this line to your application's Gemfile:
128
132
 
129
133
  ```ruby
130
- Duplo.a2a2
134
+ gem "duplo"
131
135
  ```
132
136
 
133
- If you do include it, don't worry about monkey patching - the gem
134
- works its magic by utilizing `method_missing`, so there should be no
135
- name clashes.
137
+ or install it yourself as:
136
138
 
137
- My personal preference is to drop this in `.pryrc` (or `.irbrc`):
139
+ ```sh
140
+ $ gem install duplo
141
+ ```
138
142
 
143
+ My personal preference is to drop this into `.irbrc` (or `.pryrc`):
139
144
 
140
145
  ```ruby
141
- begin
142
- require "duplo"
143
- include Duplo
144
- rescue LoadError
145
- end
146
+ require "duplo"
147
+ include Duplo
146
148
  ```
147
149
 
148
- and have those handy shortcuts available in every session, `a` and `h`
149
- in particular.
150
+ and have all those handy shortcuts available in every session.
151
+
150
152
 
151
153
 
152
154
  ## Testing
@@ -154,20 +156,10 @@ in particular.
154
156
  To test the gem, clone the repo and run:
155
157
 
156
158
  ```
157
- $ bundle
158
- $ bundle exec rake
159
+ $ bundle && bundle exec rake
159
160
  ```
160
161
 
161
162
 
162
- ## Contributing
163
-
164
- 1. [Fork it](https://github.com/topalovic/duplo/fork)
165
- 2. Create your feature branch (`git checkout -b my-new-feature`)
166
- 3. Commit your changes (`git commit -am 'Add some feature'`)
167
- 4. Push to the branch (`git push origin my-new-feature`)
168
- 5. Create a new pull request
169
-
170
-
171
163
  ## License
172
164
 
173
165
  This gem is released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -33,14 +33,16 @@ module Duplo
33
33
  end
34
34
 
35
35
  def build(part, path = [], &block)
36
+ raise %(Don't know how to build "#{part}", sorry) unless can_build? part
37
+
36
38
  part = part.dup
37
39
  brick = part.slice! BRICK
38
40
  type, size = crack brick
39
41
  toy = type.new
40
42
 
41
43
  if part.empty?
42
- _block = block_given? ? block : proc { |path| path.last }
43
- size.times { |i| add toy, _block.call(path + [i]) }
44
+ block ||= proc { |path| path.is_a?(Array) ? path.last : path }
45
+ size.times { |i| add toy, block.call(path.empty? ? i : path + [i]) }
44
46
  else
45
47
  size.times { |i| add toy, build(part, path + [i], &block) }
46
48
  end
@@ -68,11 +70,6 @@ module Duplo
68
70
 
69
71
  module_function
70
72
 
71
- def abc(n = nil)
72
- range = "a".."z"
73
- n ? range.take(n) : range.to_a
74
- end
75
-
76
73
  def respond_to_missing?(method_name, *)
77
74
  toy = method_name.to_s
78
75
  Duplo.can_build?(toy) || super
@@ -1,3 +1,3 @@
1
1
  module Duplo
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -2,21 +2,14 @@ require "spec_helper"
2
2
 
3
3
  describe Duplo do
4
4
 
5
- let(:default_size) { Duplo.default_size }
5
+ let(:default_size) { Duplo.default_size }
6
6
  let(:valid_bricks) { %w[a aa s ss h hh a0 a1h a2s33h44] }
7
7
  let(:invalid_bricks) { %w[A n 0 11 1s a2s33t44] }
8
8
 
9
- it "has a version number" do
9
+ it "has a version number" do
10
10
  expect(Duplo::VERSION).not_to be nil
11
11
  end
12
12
 
13
- describe ".abc" do
14
- it "provides alphabet" do
15
- expect(Duplo.abc).to eq ("a".."z").to_a
16
- expect(Duplo.abc 4).to eq ("a".."d").to_a
17
- end
18
- end
19
-
20
13
  describe ".respond_to?" do
21
14
  it "returns true for valid bricks" do
22
15
  valid_bricks.each do |brick|
@@ -62,6 +55,28 @@ describe Duplo do
62
55
  expect(Duplo.build brick).to eq toy
63
56
  end
64
57
  end
58
+
59
+ it "raises error when given invalid brick" do
60
+ invalid_bricks.each do |brick|
61
+ expect { Duplo.build brick }.to raise_error RuntimeError
62
+ end
63
+ end
64
+
65
+ describe "when given a block" do
66
+ let(:block) { proc { |entry| entry.class } }
67
+
68
+ describe "when given one dimension" do
69
+ it "yields entry path as integer and populates entries" do
70
+ expect(Duplo.build "a1", &block).to eq [Fixnum]
71
+ end
72
+ end
73
+
74
+ describe "when given more than one dimension" do
75
+ it "yields entry path as array and populates entries" do
76
+ expect(Duplo.build "a1a1", &block).to eq [[Array]]
77
+ end
78
+ end
79
+ end
65
80
  end
66
81
 
67
82
  describe ".smash" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duplo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikola Topalović
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-09 00:00:00.000000000 Z
11
+ date: 2015-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -71,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  version: '0'
72
72
  requirements: []
73
73
  rubyforge_project:
74
- rubygems_version: 2.4.5
74
+ rubygems_version: 2.4.6
75
75
  signing_key:
76
76
  specification_version: 4
77
77
  summary: Generate nested collections with minimum effort.