namo 0.11.0 → 0.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG +19 -0
- data/README.md +43 -0
- data/lib/Namo/Enumerable.rb +72 -0
- data/lib/Namo/VERSION.rb +1 -1
- data/lib/namo.rb +6 -67
- data/test/namo_test.rb +123 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a7dd953b56fb4f692b0e92822cb6d5dcf9a38f8645a913aedc06333441ad305
|
|
4
|
+
data.tar.gz: b492295ead6b4a9ea5647290eef7d008e86e6cbc0275176f45f2ea76b1692854
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 35a4a0acebfa4f01b83948c7a1639606cb58f9de7c0e75c8cf5886654128526cbe5554e4670503b74b5687674da00929a1b3252ee7bf30d2ecb7db976b580de5
|
|
7
|
+
data.tar.gz: ce62a04e0e1a7db2e1ec1a5f20674e000baadf3de64186ea1afe2718d8acdd36189e612aa14c6ca71a8e6330009aa0bfa380b797020ee9fbb69a6a49e9390e90
|
data/CHANGELOG
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
CHANGELOG
|
|
2
2
|
_________
|
|
3
3
|
|
|
4
|
+
20260601
|
|
5
|
+
0.12.0: Constructor widening — keyword data: and name:.
|
|
6
|
+
|
|
7
|
+
1. ~ lib/namo.rb: Namo#initialize widened from `(data = [], formulae: {})` to `(positional_data = nil, data: [], formulae: {}, name: nil)`. Data may now be passed positionally or by the `data:` keyword; positional wins when both are given (`@data = positional_data || data`). The positional default changes from `[]` to `nil` so it acts as a "not supplied" sentinel that lets `|| data` fall through to the keyword path; an explicit `Namo.new([])` still yields `@data == []` because the truthy empty array short-circuits. + `name:` keyword, stored in `@name`. Every pre-existing call site (positional data, positional data + keyword formulae, no-arg, formulae-only, and the operators' internal `self.class.new(rows, formulae: ...)`) is unaffected.
|
|
8
|
+
2. + lib/namo.rb: `attr_accessor :name`, alongside the existing `:data` and `:formulae` accessors. Gives `name` reading and `name=` post-construction mutation. Operator results carry `name == nil` (the operators construct without `name:`), establishing the subclass guard convention: subclasses guard `initialize` side effects with `return unless name`, so operator-derived instances skip them and only explicitly-named constructions fire them.
|
|
9
|
+
3. ~ test/namo_test.rb: + "construction" describe (positional data, positional + keyword formulae, no-arg empty, formulae-only, explicit `[]` honoured over the nil sentinel, keyword `data:`, positional-wins-over-keyword, and round-trips through a set operator and an Enumerable method). + "#name" describe (stored from keyword, defaults to nil, settable post-construction, nil on set-operator and Enumerable-derived results). + "subclass side-effect guard" describe — an anonymous Class.new(Namo) with a `return unless name`-guarded counter, asserting it fires for a named construction and stays untouched for an unnamed construction and an operator result.
|
|
10
|
+
4. ~ README.md: + note in the Usage section that data may be passed positionally or by `data:`, with positional winning when both are given. + "Named Namos" section: the `name:` keyword, the `name`/`name=` accessor, nil-on-derivation for operator results, and the subclass guard convention with the TradingAnalysis / argument-less `super` example.
|
|
11
|
+
5. ~ ROADMAP.md: Promote 0.12.0 from upcoming to shipped — `## Current state` bumped to 0.12.0, a `### 0.12.0 (2026-06-01)` entry added in the shipped section (written in shipped voice), and the now-redundant `## 0.12.0` upcoming section removed; fold the widened constructor into the Summary's completed vocabulary and point "next phase" at 0.13.0+.
|
|
12
|
+
6. ~ Namo::VERSION: /0.11.1/0.12.0/
|
|
13
|
+
|
|
14
|
+
20260601
|
|
15
|
+
0.11.1: Extract the subset Enumerable methods into a Namo::Enumerable module.
|
|
16
|
+
|
|
17
|
+
1. + lib/Namo/Enumerable.rb: New module Namo::Enumerable holding each and the subset-returning Enumerable methods (select plus its filter/find_all aliases, reject, sort_by, first, last, take, drop, take_while, drop_while, uniq, partition), moved verbatim from Namo. The module does `include ::Enumerable` — the leading :: is required, because under the nested `class Namo; module Enumerable` scope a bare `Enumerable` resolves to Namo::Enumerable itself and raises a cyclic-include error.
|
|
18
|
+
2. ~ lib/namo.rb: Remove the inline each and the eleven subset methods; remove `include Enumerable`; + `require_relative './Namo/Enumerable'` and `include Namo::Enumerable` (which transitively brings stdlib Enumerable into the ancestor chain below the module, so the overrides win and map/reduce/etc. still fall through). Pure reorganisation — no behaviour change.
|
|
19
|
+
3. ~ test/namo_test.rb: + Namo::Enumerable module tests — it is a Module, Namo includes it and stdlib Enumerable, and it precedes ::Enumerable in Namo.ancestors so the overrides resolve first. The existing Enumerable subset tests are unchanged and remain green, evidencing the move is behaviour-preserving.
|
|
20
|
+
4. ~ ROADMAP.md: + note in the 0.11.0 section that, as of 0.11.1, these methods live in the Namo::Enumerable module; bump Date to 20260601.
|
|
21
|
+
5. ~ Namo::VERSION: /0.11.0/0.11.1/
|
|
22
|
+
|
|
4
23
|
20260531
|
|
5
24
|
0.11.0: ~ Subset Enumerable methods (select, reject, sort_by, first, last, take, drop, take_while, drop_while, uniq, partition) return Namos
|
|
6
25
|
|
data/README.md
CHANGED
|
@@ -33,6 +33,16 @@ sales = Namo.new([
|
|
|
33
33
|
])
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
Data may be passed positionally, as above, or by the `data:` keyword where that reads more explicitly:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
sales = Namo.new(data: [
|
|
40
|
+
{product: 'Widget', quarter: 'Q1', price: 10.0, quantity: 100}
|
|
41
|
+
])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
When both are given, the positional argument wins and the keyword `data:` is ignored.
|
|
45
|
+
|
|
36
46
|
Dimensions and coordinates are inferred:
|
|
37
47
|
|
|
38
48
|
```ruby
|
|
@@ -715,6 +725,39 @@ sales[:product, :quarter, :revenue].to_h
|
|
|
715
725
|
# }
|
|
716
726
|
```
|
|
717
727
|
|
|
728
|
+
### Named Namos
|
|
729
|
+
|
|
730
|
+
A Namo can carry a name, passed by the `name:` keyword and read or set through the `name` accessor:
|
|
731
|
+
|
|
732
|
+
```ruby
|
|
733
|
+
sales = Namo.new(data: rows, name: :sales)
|
|
734
|
+
sales.name
|
|
735
|
+
# => :sales
|
|
736
|
+
|
|
737
|
+
sales.name = :renamed
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
A name defaults to `nil`, and operator results are name-less by design — the result of `+`, `*`, `select`, and the rest is a derived object, not the original, so giving it the parent's name would mislead:
|
|
741
|
+
|
|
742
|
+
```ruby
|
|
743
|
+
(sales + more).name
|
|
744
|
+
# => nil
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
This `nil`-on-derivation behaviour is what lets subclasses with side effects in `initialize` guard those effects on the name. Operator-derived instances are name-less and skip the side effects; explicitly constructed instances pass `name:` and the side effects fire:
|
|
748
|
+
|
|
749
|
+
```ruby
|
|
750
|
+
class TradingAnalysis < Namo
|
|
751
|
+
def initialize(positional_data = nil, data: [], formulae: {}, name: nil)
|
|
752
|
+
super
|
|
753
|
+
return unless name
|
|
754
|
+
register_indicators
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
`super` with no parentheses forwards every argument — positional and keyword — to `Namo#initialize` unchanged. The `return unless name` guard means a subclass need not override every operator to stop the result of `*` or `select` from re-running its construction side effects: it guards on `name` instead.
|
|
760
|
+
|
|
718
761
|
## Why?
|
|
719
762
|
|
|
720
763
|
Every other multi-dimensional array library requires you to pre-shape your data before you can work with it. Namo takes it in the form it likely already comes in.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Namo/Enumerable.rb
|
|
2
|
+
# Namo::Enumerable
|
|
3
|
+
|
|
4
|
+
class Namo
|
|
5
|
+
module Enumerable
|
|
6
|
+
include ::Enumerable
|
|
7
|
+
|
|
8
|
+
def each(&block)
|
|
9
|
+
return enum_for(:each) unless block_given?
|
|
10
|
+
@data.each{|row_data| block.call(Row.new(row_data, @formulae))}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def select(&block)
|
|
14
|
+
self.class.new(@data.select{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
15
|
+
end
|
|
16
|
+
alias_method :filter, :select
|
|
17
|
+
alias_method :find_all, :select
|
|
18
|
+
|
|
19
|
+
def reject(&block)
|
|
20
|
+
self.class.new(@data.reject{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def sort_by(&block)
|
|
24
|
+
self.class.new(@data.sort_by{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def first(n = nil)
|
|
28
|
+
if n
|
|
29
|
+
self.class.new(@data.first(n), formulae: @formulae.dup)
|
|
30
|
+
else
|
|
31
|
+
@data.first ? Row.new(@data.first, @formulae) : nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def last(n = nil)
|
|
36
|
+
if n
|
|
37
|
+
self.class.new(@data.last(n), formulae: @formulae.dup)
|
|
38
|
+
else
|
|
39
|
+
@data.last ? Row.new(@data.last, @formulae) : nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def take(n)
|
|
44
|
+
self.class.new(@data.take(n), formulae: @formulae.dup)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def drop(n)
|
|
48
|
+
self.class.new(@data.drop(n), formulae: @formulae.dup)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def take_while(&block)
|
|
52
|
+
self.class.new(@data.take_while{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def drop_while(&block)
|
|
56
|
+
self.class.new(@data.drop_while{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def uniq(&block)
|
|
60
|
+
rows = block ? @data.uniq{|row| block.call(Row.new(row, @formulae))} : @data.uniq
|
|
61
|
+
self.class.new(rows, formulae: @formulae.dup)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def partition(&block)
|
|
65
|
+
matches, non_matches = @data.partition{|row| block.call(Row.new(row, @formulae))}
|
|
66
|
+
[
|
|
67
|
+
self.class.new(matches, formulae: @formulae.dup),
|
|
68
|
+
self.class.new(non_matches, formulae: @formulae.dup),
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/Namo/VERSION.rb
CHANGED
data/lib/namo.rb
CHANGED
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
|
|
4
4
|
require_relative './Namo/NegatedDimension'
|
|
5
5
|
require_relative './Namo/Row'
|
|
6
|
+
require_relative './Namo/Enumerable'
|
|
6
7
|
require_relative './Namo/VERSION'
|
|
7
8
|
require_relative './Symbol'
|
|
8
9
|
|
|
9
10
|
class Namo
|
|
10
|
-
include Enumerable
|
|
11
|
+
include Namo::Enumerable
|
|
11
12
|
|
|
12
13
|
attr_accessor :data
|
|
13
14
|
attr_accessor :formulae
|
|
15
|
+
attr_accessor :name
|
|
14
16
|
|
|
15
17
|
def dimensions
|
|
16
18
|
data_dimensions + derived_dimensions
|
|
@@ -76,70 +78,6 @@ class Namo
|
|
|
76
78
|
@formulae[name] = proc
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
def each(&block)
|
|
80
|
-
return enum_for(:each) unless block_given?
|
|
81
|
-
@data.each{|row_data| block.call(Row.new(row_data, @formulae))}
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def select(&block)
|
|
85
|
-
self.class.new(@data.select{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
86
|
-
end
|
|
87
|
-
alias_method :filter, :select
|
|
88
|
-
alias_method :find_all, :select
|
|
89
|
-
|
|
90
|
-
def reject(&block)
|
|
91
|
-
self.class.new(@data.reject{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def sort_by(&block)
|
|
95
|
-
self.class.new(@data.sort_by{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def first(n = nil)
|
|
99
|
-
if n
|
|
100
|
-
self.class.new(@data.first(n), formulae: @formulae.dup)
|
|
101
|
-
else
|
|
102
|
-
@data.first ? Row.new(@data.first, @formulae) : nil
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def last(n = nil)
|
|
107
|
-
if n
|
|
108
|
-
self.class.new(@data.last(n), formulae: @formulae.dup)
|
|
109
|
-
else
|
|
110
|
-
@data.last ? Row.new(@data.last, @formulae) : nil
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def take(n)
|
|
115
|
-
self.class.new(@data.take(n), formulae: @formulae.dup)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def drop(n)
|
|
119
|
-
self.class.new(@data.drop(n), formulae: @formulae.dup)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def take_while(&block)
|
|
123
|
-
self.class.new(@data.take_while{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def drop_while(&block)
|
|
127
|
-
self.class.new(@data.drop_while{|row| block.call(Row.new(row, @formulae))}, formulae: @formulae.dup)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def uniq(&block)
|
|
131
|
-
rows = block ? @data.uniq{|row| block.call(Row.new(row, @formulae))} : @data.uniq
|
|
132
|
-
self.class.new(rows, formulae: @formulae.dup)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def partition(&block)
|
|
136
|
-
matches, non_matches = @data.partition{|row| block.call(Row.new(row, @formulae))}
|
|
137
|
-
[
|
|
138
|
-
self.class.new(matches, formulae: @formulae.dup),
|
|
139
|
-
self.class.new(non_matches, formulae: @formulae.dup),
|
|
140
|
-
]
|
|
141
|
-
end
|
|
142
|
-
|
|
143
81
|
def +(other)
|
|
144
82
|
raise_unless_namo(other)
|
|
145
83
|
raise_unless_matching_data_dimensions(other)
|
|
@@ -309,8 +247,9 @@ class Namo
|
|
|
309
247
|
end
|
|
310
248
|
end
|
|
311
249
|
|
|
312
|
-
def initialize(
|
|
313
|
-
@data = data
|
|
250
|
+
def initialize(positional_data = nil, data: [], formulae: {}, name: nil)
|
|
251
|
+
@data = positional_data || data
|
|
314
252
|
@formulae = formulae
|
|
253
|
+
@name = name
|
|
315
254
|
end
|
|
316
255
|
end
|
data/test/namo_test.rb
CHANGED
|
@@ -33,6 +33,113 @@ describe Namo do
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
describe "construction" do
|
|
37
|
+
it "accepts positional data" do
|
|
38
|
+
_(Namo.new([{x: 1}]).data).must_equal [{x: 1}]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "accepts positional data with keyword formulae" do
|
|
42
|
+
namo = Namo.new([{x: 1}], formulae: {y: proc{|r| r[:x] * 2}})
|
|
43
|
+
_(namo.data).must_equal [{x: 1}]
|
|
44
|
+
_(namo.values(:y)).must_equal [2]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "produces an empty Namo with no arguments" do
|
|
48
|
+
namo = Namo.new
|
|
49
|
+
_(namo.data).must_equal []
|
|
50
|
+
_(namo.formulae).must_equal({})
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "accepts keyword formulae with no data" do
|
|
54
|
+
namo = Namo.new(formulae: {y: proc{|r| r[:x] * 2}})
|
|
55
|
+
_(namo.data).must_equal []
|
|
56
|
+
_(namo.derived_dimensions).must_equal [:y]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "honours an explicit empty positional array over the nil sentinel" do
|
|
60
|
+
_(Namo.new([]).data).must_equal []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "accepts data by keyword" do
|
|
64
|
+
_(Namo.new(data: [{x: 1}]).data).must_equal [{x: 1}]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "lets positional data win when both positional and keyword data are given" do
|
|
68
|
+
_(Namo.new([{x: 1}], data: [{x: 2}]).data).must_equal [{x: 1}]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "survives a round-trip through a set operator" do
|
|
72
|
+
a = Namo.new([{x: 1}])
|
|
73
|
+
b = Namo.new([{x: 2}])
|
|
74
|
+
_((a + b).data).must_equal [{x: 1}, {x: 2}]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "survives a round-trip through an Enumerable method" do
|
|
78
|
+
namo = Namo.new([{x: 1}, {x: 2}])
|
|
79
|
+
_(namo.select{|row| row[:x] > 1}.data).must_equal [{x: 2}]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "#name" do
|
|
84
|
+
it "stores a name passed by keyword" do
|
|
85
|
+
_(Namo.new([{x: 1}], name: :foo).name).must_equal :foo
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "defaults to nil when no name is passed" do
|
|
89
|
+
_(Namo.new([{x: 1}]).name).must_be_nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "is settable post-construction" do
|
|
93
|
+
namo = Namo.new([{x: 1}])
|
|
94
|
+
namo.name = :bar
|
|
95
|
+
_(namo.name).must_equal :bar
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "is nil on a Namo derived from a set operator" do
|
|
99
|
+
a = Namo.new([{x: 1}], name: :a)
|
|
100
|
+
b = Namo.new([{x: 2}], name: :b)
|
|
101
|
+
_((a + b).name).must_be_nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "is nil on a Namo derived from an Enumerable method" do
|
|
105
|
+
namo = Namo.new([{x: 1}, {x: 2}], name: :original)
|
|
106
|
+
_(namo.select{|row| row[:x] > 1}.name).must_be_nil
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe "subclass side-effect guard" do
|
|
111
|
+
before do
|
|
112
|
+
@guard_class = Class.new(Namo) do
|
|
113
|
+
def self.fired
|
|
114
|
+
@fired ||= []
|
|
115
|
+
end
|
|
116
|
+
def initialize(positional_data = nil, data: [], formulae: {}, name: nil)
|
|
117
|
+
super
|
|
118
|
+
return unless name
|
|
119
|
+
self.class.fired << name
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "fires guarded side effects for an explicitly named construction" do
|
|
125
|
+
@guard_class.new(data: [{x: 1}], name: :foo)
|
|
126
|
+
_(@guard_class.fired).must_equal [:foo]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "skips guarded side effects for an unnamed construction" do
|
|
130
|
+
@guard_class.new(data: [{x: 1}])
|
|
131
|
+
_(@guard_class.fired).must_equal []
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "skips guarded side effects for an operator result" do
|
|
135
|
+
a = @guard_class.new(data: [{x: 1}], name: :a)
|
|
136
|
+
b = @guard_class.new(data: [{x: 2}], name: :b)
|
|
137
|
+
@guard_class.fired.clear
|
|
138
|
+
_((a + b).name).must_be_nil
|
|
139
|
+
_(@guard_class.fired).must_equal []
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
36
143
|
describe "#dimensions" do
|
|
37
144
|
it "infers dimensions from hash keys" do
|
|
38
145
|
_(sales.dimensions).must_equal [:product, :quarter, :price, :quantity]
|
|
@@ -913,6 +1020,22 @@ describe Namo do
|
|
|
913
1020
|
end
|
|
914
1021
|
end
|
|
915
1022
|
|
|
1023
|
+
describe "Namo::Enumerable module" do
|
|
1024
|
+
it "is a Module supplying the subset methods" do
|
|
1025
|
+
_(Namo::Enumerable).must_be_kind_of Module
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
it "is included in Namo, transitively including stdlib Enumerable" do
|
|
1029
|
+
_(Namo.include?(Namo::Enumerable)).must_equal true
|
|
1030
|
+
_(Namo.include?(Enumerable)).must_equal true
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
it "sits above stdlib Enumerable so its overrides win" do
|
|
1034
|
+
ancestors = Namo.ancestors
|
|
1035
|
+
_(ancestors.index(Namo::Enumerable) < ancestors.index(::Enumerable)).must_equal true
|
|
1036
|
+
end
|
|
1037
|
+
end
|
|
1038
|
+
|
|
916
1039
|
describe "#+" do
|
|
917
1040
|
let(:more_data) do
|
|
918
1041
|
[
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: namo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
@@ -64,6 +64,7 @@ files:
|
|
|
64
64
|
- LICENSE
|
|
65
65
|
- README.md
|
|
66
66
|
- Rakefile
|
|
67
|
+
- lib/Namo/Enumerable.rb
|
|
67
68
|
- lib/Namo/NegatedDimension.rb
|
|
68
69
|
- lib/Namo/Row.rb
|
|
69
70
|
- lib/Namo/VERSION.rb
|