totally_lazy 0.0.5 → 0.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef27c17e829a30f3c3efd0bacdb6023066e85326
4
- data.tar.gz: d583a528661e3c190245c64ffce9cf9b8093d55a
3
+ metadata.gz: 07387e8a468855a7da2085b260925debed565e11
4
+ data.tar.gz: cf13015fc8e70f75561464263ae624a18f59cedb
5
5
  SHA512:
6
- metadata.gz: 32ed21dfa78360ba8dec458c2f6646a4af09a448957b84e51c0ee686aa1fb6e031334f676e7bb5a51e759bceb9c8e88a942f022b39c80189e64877949f121aa2
7
- data.tar.gz: 9e903a0e2716f72c524753d35de1a5ecfdb0f71228b6aa4aef1f0f55e92c3bdf9a6cb38c9fdfad99acc49a19f2501992d4175180daa1b7805cde33b84f5bb305
6
+ metadata.gz: 01a92b3af2d701c2a900c74282d666642ed00cead1aac4d3781dbe5ece2ca2439d84cda0923c0e1ec3420f108443690061cfc18233281d484f07c7750a94a867
7
+ data.tar.gz: 164b856f25c3ebed7cb00134b118dc5815de8d522f3bc5cf395dc9f626b4ac118049528f7cc09a4b7b65532ae7f4c9f473fdd212d1a83f71e0a4364c52695f46
data/README.md CHANGED
@@ -17,10 +17,12 @@ This is a port of the java functional library [Totally Lazy](https://code.google
17
17
 
18
18
  ### Install
19
19
 
20
+ This gem requires ruby 2.x.x
21
+
20
22
  In your bundler Gemfile
21
23
 
22
24
  ```ruby
23
- gem totally_lazy, '~>0.0.4'
25
+ gem totally_lazy, '~>0.0.6'
24
26
  ```
25
27
 
26
28
  Or with rubygems
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
data/lib/pair.rb CHANGED
@@ -25,6 +25,16 @@ module Pair
25
25
  @second.call
26
26
  end
27
27
 
28
+ def first=(v)
29
+ @first = -> { v }
30
+ end
31
+ alias key= first=
32
+
33
+ def second=(v)
34
+ @second = -> { v }
35
+ end
36
+ alias value= second=
37
+
28
38
  def each(&block)
29
39
  [first,second].each do |i|
30
40
  block.call(i)
@@ -3,30 +3,23 @@ module Predicates
3
3
  module Compare
4
4
 
5
5
  def equals(value)
6
- -> (v, meth=:self, invert=false) do
7
- invert ? inverted_value(v, value, meth, :==) : regular_value(v, value, meth, :==)
8
- end
6
+ value_predicate(:equals,:==,value)
9
7
  end
10
8
 
11
9
  alias equal_to equals
12
10
 
13
11
  def greater_than(value)
14
- -> (v, meth=:self, invert=false) do
15
- invert ? inverted_value(v, value, meth, :>) : regular_value(v, value, meth, :>)
16
- end
12
+ value_predicate(:greater_than,:>,value)
17
13
  end
18
14
 
19
15
  def less_than(value)
20
- -> (v, meth=:self, invert=false) do
21
- invert ? inverted_value(v, value, meth, :<) : regular_value(v, value, meth, :<)
22
- end
16
+ value_predicate(:less_than,:<,value)
23
17
  end
24
18
 
25
- def matches(regex)
26
- -> (v, meth=:self, invert=false) do
27
- invert ? inverted_regex(v, regex, meth) : regular_regex(v, regex, meth)
28
- end
19
+ def matches(value)
20
+ regex_predicate(:matches,value)
29
21
  end
22
+
30
23
  end
31
24
 
32
25
  end
@@ -3,19 +3,19 @@ module Predicates
3
3
  module Conversions
4
4
 
5
5
  def as_string
6
- -> (v) { v.to_s }
6
+ simple_predicate(:as_string, -> (v) { v.to_s } )
7
7
  end
8
8
 
9
9
  def as_int
10
- -> (v) { Type.responds(v, :to_i); v.to_i }
10
+ simple_predicate(:as_int, -> (v) { Type.responds(v, :to_i); v.to_i } )
11
11
  end
12
12
 
13
13
  def as_float
14
- -> (v) { Type.responds(v, :to_i); v.to_f }
14
+ simple_predicate(:as_float, -> (v) { Type.responds(v, :to_f); v.to_f } )
15
15
  end
16
16
 
17
17
  def as_array
18
- -> (v) { [v] }
18
+ simple_predicate(:as_array, -> (v) { [v] } )
19
19
  end
20
20
 
21
21
  end
@@ -3,15 +3,11 @@ module Predicates
3
3
  module Numbers
4
4
 
5
5
  def even
6
- -> (v, meth=:self, invert=false) do
7
- invert ? inverted(v, meth, :even?) : regular(v, meth, :even?)
8
- end
6
+ self_predicate(:even,:even?)
9
7
  end
10
8
 
11
9
  def odd
12
- -> (v, meth=:self, invert=false) do
13
- invert ? inverted(v, meth, :odd?) : regular(v, meth, :odd?)
14
- end
10
+ self_predicate(:odd,:odd?)
15
11
  end
16
12
  #
17
13
  # def between(lower, higher)
@@ -1,57 +1,141 @@
1
1
  module Predicates
2
2
 
3
- def inverted(v, meth, pred)
4
- if meth == :self
5
- Type.responds(v, pred)
6
- v unless v.send(pred)
3
+ class Predicate
4
+
5
+ def inverted(v, meth, pred)
6
+ if meth == :self
7
+ Type.responds(v, pred)
8
+ v unless v.send(pred)
9
+ end
10
+ end
11
+
12
+ def regular(v, meth, pred)
13
+ if meth == :self
14
+ Type.responds(v, pred)
15
+ v if v.send(pred)
16
+ else
17
+ r = v.send(meth)
18
+ Type.responds(r, pred)
19
+ v if r.send(pred)
20
+ end
21
+ end
22
+
23
+ def inverted_value(v, value, meth, pred)
24
+ if meth == :self
25
+ Type.responds(v, pred)
26
+ v unless v.send(pred, value)
27
+ end
28
+ end
29
+
30
+ def regular_value(v, value, meth, pred)
31
+ if meth == :self
32
+ Type.responds(v, pred)
33
+ v if v.send(pred, value)
34
+ else
35
+ r = v.send(meth)
36
+ Type.responds(r, pred)
37
+ v if r.send(pred, value)
38
+ end
39
+ end
40
+
41
+ def regular_regex(v, regex, meth)
42
+ if meth == :self
43
+ v if v.to_s.match(regex)
44
+ else
45
+ r = v.send(meth)
46
+ v if r.to_s.match(regex)
47
+ end
7
48
  end
8
- end
9
49
 
10
- def regular(v, meth, pred)
11
- if meth == :self
12
- Type.responds(v, pred)
13
- v if v.send(pred)
14
- else
15
- r = v.send(meth)
16
- Type.responds(r, pred)
17
- v if r.send(pred)
50
+ def inverted_regex(v, regex, meth)
51
+ if meth == :self
52
+ v unless v.to_s.match(regex)
53
+ else
54
+ r = v.send(meth)
55
+ v unless r.to_s.match(regex)
56
+ end
18
57
  end
58
+
59
+ end
60
+
61
+ def value_predicate(name, pred, value)
62
+ ValuePredicate.new(name, pred, value)
63
+ end
64
+
65
+ def regex_predicate(name, value)
66
+ RegexPredicate.new(name, value)
67
+ end
68
+
69
+ def self_predicate(name,pred)
70
+ SelfPredicate.new(name,pred)
71
+ end
72
+
73
+ def simple_predicate(name,exec)
74
+ SimplePredicate.new(name,exec)
19
75
  end
20
76
 
21
- def inverted_value(v, value, meth, pred)
22
- if meth == :self
23
- Type.responds(v, pred)
24
- v unless v.send(pred, value)
77
+
78
+ class ValuePredicate < Predicates::Predicate
79
+
80
+ attr_reader :name, :pred, :value
81
+
82
+ def initialize(name, pred, value)
83
+ @name = name
84
+ @pred = pred
85
+ @value = value
86
+ end
87
+
88
+ def exec
89
+ -> (v, meth=:self, invert=false) do
90
+ invert ? inverted_value(v, @value, meth, @pred) : regular_value(v, @value, meth, @pred)
91
+ end
25
92
  end
93
+
26
94
  end
27
95
 
28
- def regular_value(v, value, meth, pred)
29
- if meth == :self
30
- Type.responds(v, pred)
31
- v if v.send(pred, value)
32
- else
33
- r = v.send(meth)
34
- Type.responds(r, pred)
35
- v if r.send(pred, value)
96
+ class SelfPredicate < Predicates::Predicate
97
+
98
+ attr_reader :name, :pred
99
+
100
+ def initialize(name, pred)
101
+ @name = name
102
+ @pred = pred
103
+ end
104
+
105
+ def exec
106
+ -> (v, meth=:self, invert=false) do
107
+ invert ? inverted(v, meth, @pred) : regular(v, meth, @pred)
108
+ end
36
109
  end
110
+
37
111
  end
38
112
 
39
- def regular_regex(v, regex, meth)
40
- if meth == :self
41
- v if v.to_s.match(regex)
42
- else
43
- r = v.send(meth)
44
- v if r.to_s.match(regex)
113
+ class SimplePredicate < Predicates::Predicate
114
+ attr_reader :name, :exec
115
+
116
+ def initialize(name, exec)
117
+ @name = name
118
+ @exec = exec
45
119
  end
120
+
46
121
  end
47
122
 
48
- def inverted_regex(v, regex, meth)
49
- if meth == :self
50
- v unless v.to_s.match(regex)
51
- else
52
- r = v.send(meth)
53
- v unless r.to_s.match(regex)
123
+ class RegexPredicate < Predicates::Predicate
124
+
125
+ attr_reader :name, :value
126
+
127
+ def initialize(name, value)
128
+ @name = name
129
+ @value = value
54
130
  end
131
+
132
+ def exec
133
+ -> (v, meth=:self, invert=false) do
134
+ invert ? inverted_regex(v, @value, meth) : regular_regex(v, @value, meth)
135
+ end
136
+ end
137
+
55
138
  end
56
139
 
140
+
57
141
  end
@@ -5,9 +5,9 @@ class WhereProcessor
5
5
 
6
6
  def apply(predicates, invert=false)
7
7
  if invert
8
- @value if predicates.map { |x| x.value.call(@value, x.key) }.contains?(nil)
8
+ @value if predicates.map { |x| x.value.exec.call(@value, x.key) }.contains?(nil)
9
9
  else
10
- @value unless predicates.map { |x| x.value.call(@value, x.key) }.contains?(nil)
10
+ @value unless predicates.map { |x| x.value.exec.call(@value, x.key) }.contains?(nil)
11
11
  end
12
12
  end
13
13
  end
data/lib/sequence.rb CHANGED
@@ -4,6 +4,9 @@ end
4
4
  class UnsupportedTypeException < RuntimeError
5
5
  end
6
6
 
7
+ class UnsupportedMethodException < RuntimeError
8
+ end
9
+
7
10
  module Sequences
8
11
 
9
12
  # Creates a sequence
@@ -84,7 +87,7 @@ module Sequences
84
87
  def map(predicate=nil, &block)
85
88
  if predicate
86
89
  Sequence.new(self) { |yielder, val|
87
- v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.call(val)
90
+ v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
88
91
  yielder << v unless v.nil?
89
92
  }
90
93
  else
@@ -121,7 +124,7 @@ module Sequences
121
124
  def select(predicate=nil, &block)
122
125
  if predicate
123
126
  Sequence.new(self) { |yielder, val|
124
- v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.call(val)
127
+ v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
125
128
  yielder << v unless v.nil?
126
129
  }
127
130
  else
@@ -139,7 +142,7 @@ module Sequences
139
142
  def reject(predicate=nil, &block)
140
143
  if predicate
141
144
  Sequence.new(self) { |yielder, val|
142
- v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates, true) : predicate.call(val, :self, true)
145
+ v = predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates, true) : predicate.exec.call(val, :self, true)
143
146
  yielder << v unless v.nil?
144
147
  }
145
148
  else
@@ -187,15 +190,15 @@ module Sequences
187
190
  end
188
191
 
189
192
  def take(n)
190
- taken = 0
191
- Sequence.new(self) { |yielder, val|
192
- if taken < n
193
- yielder << val
194
- taken += 1
195
- else
196
- raise StopIteration
193
+ Sequence.new(Sequence::Generator.new do |g|
194
+ self.each_with_index do |v, i|
195
+ if i < n
196
+ g.yield v
197
+ else
198
+ raise StopIteration
199
+ end
197
200
  end
198
- }
201
+ end)
199
202
  end
200
203
 
201
204
  def take_while(&block)
@@ -334,6 +337,18 @@ module Sequences
334
337
  end)
335
338
  end
336
339
 
340
+ def to_maps(symbolize=true)
341
+ Sequence.new(Sequence::Generator.new do |g|
342
+ self.each_slice(2) do |k, v|
343
+ if symbolize
344
+ g.yield k.to_s.to_sym => v
345
+ else
346
+ g.yield k => v
347
+ end
348
+ end
349
+ end)
350
+ end
351
+
337
352
  def from_pairs
338
353
  Sequence.new(Sequence::Generator.new do |g|
339
354
  self.entries.map { |e| Type.check(e, Pair::Pair); [e.key, e.value] }.flatten.each { |i| g.yield i }
@@ -372,6 +387,25 @@ module Sequences
372
387
  end
373
388
  end
374
389
 
390
+ def update(item)
391
+ Sequence.new(Sequence::Generator.new do |g|
392
+ if item.is_a?(Hash)
393
+ self.map do |e|
394
+ item.map { |k, v|
395
+ raise(UnsupportedMethodException.new, "Tried to call method: #{k} on #{e.class} but method not supported") unless e.respond_to?(k) or e.respond_to?(":#{k}=")
396
+ begin
397
+ e.send(k, v) if e.respond_to?(k); e
398
+ rescue
399
+ e.send("#{k}=", v) if e.respond_to?("#{k}="); e
400
+ end
401
+ }.first
402
+ end
403
+ else
404
+ self.map { item }
405
+ end.each { |i| g.yield i }
406
+ end)
407
+ end
408
+
375
409
  def marshal_dump
376
410
  serialize
377
411
  end
@@ -396,6 +430,24 @@ module Sequences
396
430
  to_a.flatten
397
431
  end
398
432
 
433
+ def sorting_by(*attr, &block)
434
+ if attr.empty?
435
+ Sequence.new(Sequence::Generator.new do |g|
436
+ self.sort_by { |e| block.call(e) }.each { |i| g.yield i }
437
+ end)
438
+ else
439
+ Sequence.new(Sequence::Generator.new do |g|
440
+ self.sort_by { |e| attr.map{|v| e.send(v)} }.each { |i| g.yield i }
441
+ end)
442
+ end
443
+ end
444
+
445
+ def sorting
446
+ Sequence.new(Sequence::Generator.new do |g|
447
+ self.sort.each { |i| g.yield i }
448
+ end)
449
+ end
450
+
399
451
  def get_or_else(index, or_else)
400
452
  blank?(sequence[index]) ? or_else : sequence[index]
401
453
  end
@@ -418,7 +470,7 @@ module Sequences
418
470
  if predicate
419
471
  Sequence.new(Sequence::Generator.new do |g|
420
472
  Parallel.map(self.entries, options) { |val|
421
- predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.call(val)
473
+ predicate.is_a?(WherePredicate) ? WhereProcessor.new(val).apply(predicate.predicates) : predicate.exec.call(val)
422
474
  }.each { |i| g.yield i unless i.nil? }
423
475
  end)
424
476
  else
data/lib/totally_lazy.rb CHANGED
@@ -14,6 +14,7 @@ require_relative 'predicates/where_processor'
14
14
  require_relative 'parallel/parallel'
15
15
  require_relative 'generators'
16
16
  require_relative 'any'
17
+ require_relative 'utils'
17
18
 
18
19
  include Sequences
19
20
  include Option
@@ -25,6 +26,7 @@ include Predicates::Compare
25
26
  include Predicates::Where
26
27
  include Generators
27
28
  include Any
29
+ include Maps
28
30
 
29
31
 
30
32
  # p sequence(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).filter(
@@ -127,6 +129,35 @@ include Any
127
129
  # p f - s
128
130
 
129
131
 
132
+ # p Seq.range(1,20).filter(odd).update(10).to_a
133
+
134
+ # require 'ostruct'
135
+ # #
136
+ # #
137
+ # # p Seq.repeat(->{OpenStruct.new(name:Any.string(5),age:Any.int(2))}).take(100000).update(age:11,name:'woops').take(1000).head
138
+ # #
139
+ # # p sequence({apple:1,pear:2}).each_slice(2).map{|s| [s[0],s[1]]}.to_a
140
+ #
141
+ # a = Seq.range(1,10).map{|n| OpenStruct.new(name:Any.string(5),age:Any.int(2)) }.to_a
142
+ #
143
+ # orig = sequence(a)
144
+ #
145
+ # updates = orig.filter(where(age:greater_than(70))).update(age:2)
146
+ #
147
+ # p orig.count
148
+ # p updates.count
149
+
150
+ # p where(id:equals(1)).as_map.entries
151
+
152
+ #
153
+
154
+ # p sequence(1,2,3,4).filter(where(is equal_to(2))).entries
155
+
156
+ # p where(is equal_to 2).predicates.head.value
157
+
158
+
159
+ # p sequence(1,2,3,4,5,6).map(as_string).to_a
160
+
130
161
 
131
162
 
132
163
 
data/lib/utils.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Maps
2
+
3
+ module_function
4
+
5
+ def merge(sequence_of_maps)
6
+ sequence_of_maps.reduce({}){|a,b| a.merge(b) }
7
+ end
8
+
9
+ end
@@ -192,4 +192,26 @@ describe 'Sequence' do
192
192
  expect(sequence(:name,'kings',:age,39).in_pairs.to_a).to eq(sequence(pair(:name,'kings'),pair(:age,39)).to_a)
193
193
  end
194
194
 
195
+ it 'should update items in a sequence' do
196
+ expect(Seq.repeat(->{OpenStruct.new(name:Any.string(5),age:Any.int(2))}).take(100000).update(age:11,name:'woops').take(10).map{|s| [s.name,s.age]}.head).to eq(['woops',11])
197
+ expect(Seq.range(1,10).filter(odd).update(2)).to eq(sequence(2,2,2,2,2))
198
+ end
199
+
200
+ it 'should sort by attributes' do
201
+ expect(sequence(pair(:a,1),pair(:d,4),pair(:c,3),pair(:b,2)).sorting_by{|e| e.value }.to_a).to eq([{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}])
202
+ expect(sequence(pair(:a,1),pair(:d,4),pair(:c,3),pair(:b,2)).sorting_by(:value).to_a).to eq([{:a=>1}, {:b=>2}, {:c=>3}, {:d=>4}])
203
+ expect(sequence(
204
+ OpenStruct.new(first_name:'David',age:19,job:'computers'),
205
+ OpenStruct.new(first_name:'Chris',age:19,job:'art'),
206
+ OpenStruct.new(first_name:'Andrew',age:32,job:'dancing'),
207
+ OpenStruct.new(first_name:'Andrew',age:18,job:'dancing'),
208
+ ).sorting_by{|e| [e.first_name,e.age] }.map{|e| [e.first_name,e.age,e.job]}.to_a).to eq([['Andrew', 18, 'dancing'], ['Andrew', 32, 'dancing'], ['Chris', 19, 'art'], ['David', 19, 'computers']])
209
+ end
210
+
211
+ it 'should sort' do
212
+ expect(sequence(5,2,3,1,4).sorting).to eq(sequence(1,2,3,4,5))
213
+ end
214
+
215
+
216
+
195
217
  end
data/spec/util_spec.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'Maps' do
4
+
5
+ it 'should return a sequence of maps as a merged map' do
6
+ expect(Maps.merge(sequence(:a,2,:b,4).to_maps)).to eq({a:2,b:4})
7
+ expect(Maps.merge(sequence(1,2,3,4).to_maps(false))).to eq({1=>2,3=>4})
8
+ end
9
+
10
+ end
data/totally_lazy.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: totally_lazy 0.0.5 ruby lib
5
+ # stub: totally_lazy 0.0.6 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "totally_lazy"
9
- s.version = "0.0.5"
9
+ s.version = "0.0.6"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Kingsley Hendrickse"]
14
- s.date = "2014-09-22"
14
+ s.date = "2014-10-03"
15
15
  s.description = "Port of java functional library totally lazy to ruby"
16
16
  s.email = "kingsleyhendrickse@me.com"
17
17
  s.extra_rdoc_files = [
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
44
44
  "lib/sequence.rb",
45
45
  "lib/totally_lazy.rb",
46
46
  "lib/type_check.rb",
47
+ "lib/utils.rb",
47
48
  "spec/functor_spec.rb",
48
49
  "spec/generators_spec.rb",
49
50
  "spec/option_spec.rb",
@@ -53,6 +54,7 @@ Gem::Specification.new do |s|
53
54
  "spec/serialization_spec.rb",
54
55
  "spec/spec_helper.rb",
55
56
  "spec/type_check_spec.rb",
57
+ "spec/util_spec.rb",
56
58
  "totally_lazy.gemspec"
57
59
  ]
58
60
  s.homepage = "http://github.com/kingsleyh/totally_lazy"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: totally_lazy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kingsley Hendrickse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-22 00:00:00.000000000 Z
11
+ date: 2014-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -169,6 +169,7 @@ files:
169
169
  - lib/sequence.rb
170
170
  - lib/totally_lazy.rb
171
171
  - lib/type_check.rb
172
+ - lib/utils.rb
172
173
  - spec/functor_spec.rb
173
174
  - spec/generators_spec.rb
174
175
  - spec/option_spec.rb
@@ -178,6 +179,7 @@ files:
178
179
  - spec/serialization_spec.rb
179
180
  - spec/spec_helper.rb
180
181
  - spec/type_check_spec.rb
182
+ - spec/util_spec.rb
181
183
  - totally_lazy.gemspec
182
184
  homepage: http://github.com/kingsleyh/totally_lazy
183
185
  licenses: