namo 0.32.4 → 0.32.5
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 +12 -3
- data/README.md +13 -5
- data/lib/Namo/VERSION.rb +1 -1
- data/lib/namo.rb +4 -3
- data/namo.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fca34f0fc6464ae1bbb80a5df45f40b63c496369b7cfbc6b32090e26bf0938f3
|
|
4
|
+
data.tar.gz: f156784556a7fcd2a28cef6f44178e0c4b115617cd5e64f173cfb42ca768fb53
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e47d75b0e5a23a4f131de7d8d3865dc27ad74ef91a2e87cb7c8d36a2c127784a11cf1b767978ec54b6fabf48c99f25f9a09839e229d3abd36f3851d801549257
|
|
7
|
+
data.tar.gz: c1f4a2ae0e3946c4c02e1f4d643b18666214224b58602ffd9185410f7e66ea949d96a1521582f98b095b9cf7b703f665014e8e42f43ed7ef65a4647da3b8efc5
|
data/CHANGELOG
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 20261003
|
|
4
|
+
|
|
5
|
+
0.32.5: Documentation clean up.
|
|
6
|
+
|
|
7
|
+
1. ~ README.md: + what Symbol#-@ costs, and why `/` dedupes.
|
|
8
|
+
2. ~ COMPARISON.md: decomposition is relational projection, dedup and all.
|
|
9
|
+
3. ~ ROADMAP.md: + the 0.9.0 memoir's 2026-10 note and the "How the demonstration ships" section.
|
|
10
|
+
4. ~ lib/namo.rb: the inspected_rows comment corrected.
|
|
11
|
+
5. ~ namo.gemspec: the gem name heads the file list.
|
|
12
|
+
6. ~ CHANGELOG: the 0.21.0, 0.22.0 and 0.23.0 entries aligned with the commit message for each.
|
|
13
|
+
7. ~ Namo::VERSION: /0.32.4/0.32.5/
|
|
14
|
+
|
|
3
15
|
## 20260828
|
|
4
16
|
|
|
5
17
|
0.32.4: ~ README.md: + Console, the command the gem has shipped since 0.32.0 going unmentioned until now.
|
|
@@ -10,7 +22,6 @@
|
|
|
10
22
|
4. ~ CHANGELOG: the 20260828 releases gather under one heading, as 20260824 and 20260826 gather theirs. Four releases in a day had taken a heading each.
|
|
11
23
|
5. ~ Namo::VERSION: /0.32.3/0.32.4/
|
|
12
24
|
|
|
13
|
-
|
|
14
25
|
0.32.3: ~ install.sh: + ruby-install, for a machine with no package manager at all; the handover is to a clone's own bin/namo where the script was run from one.
|
|
15
26
|
|
|
16
27
|
1. ~ install.sh: + install_ruby_install, + ruby_from_ruby_install. Where no package manager is found and Homebrew is declined, ruby-install is offered — fetched from its latest release rather than a pinned version, built with make as root, and used to build Ruby. It is the last thing tried and the only route here which builds Ruby rather than fetching it.
|
|
@@ -21,7 +32,6 @@
|
|
|
21
32
|
6. ~ install.sh: + repository, and hand_over takes the clone it was given. install_namo is the bootstrap for the handover and nothing else — a way to have a namo command to run — so a script run from a checkout hands over to that checkout's bin/namo and leaves the gem to `namo setup`, which installs it as its own first act. A checkout with the gem not yet installed now works as it stands, and the gem is named once rather than by both scripts in turn. 0.32.1 had taken the path lookup out for being unconditional, which failed piped from curl where the working directory is not a checkout; it is guarded now on $0 being a readable file beside both bin/namo and the gemspec, none of which holds for the shell's own name, so the curl route finds nothing and installs the gem as it did.
|
|
22
33
|
7. ~ Namo::VERSION: /0.32.2/0.32.3/
|
|
23
34
|
|
|
24
|
-
|
|
25
35
|
0.32.2: ~ install.sh: the one command ends with namo runnable from anywhere.
|
|
26
36
|
|
|
27
37
|
1. ~ install.sh: + add_to_path, + gem_bin_directory, + shell_configuration_file. gem puts the command in a directory which is on the PATH on some machines and not on others — Homebrew's ruby puts it somewhere which is not — so the run ended by naming the directory and stopping. It now offers to add it to the shell's configuration file, and adds it to the PATH of the run itself so that `namo setup` happens rather than being left as a further instruction.
|
|
@@ -30,7 +40,6 @@
|
|
|
30
40
|
4. ~ install.sh: + apt-get, dnf, pacman and zypper alongside Homebrew and MacPorts, so the script reaches a Ruby on Linux rather than offering to install Homebrew on a machine which has apt. + install_with_sudo, every package manager but Homebrew installing as root, so the password is asked for by name rather than arriving unannounced.
|
|
31
41
|
5. ~ Namo::VERSION: /0.32.1/0.32.2/
|
|
32
42
|
|
|
33
|
-
|
|
34
43
|
0.32.1: ~ install.sh: it runs the same piped from curl as from a clone, and forces no package manager; ~ README.md: + the one-line install.
|
|
35
44
|
|
|
36
45
|
1. ~ install.sh: the handover is to `namo setup` on the PATH rather than to bin/namo beside the script. It had found bin/namo by its own path, so piped from curl it looked in the working directory and failed there. It now finds nothing by its path and so runs from anywhere. The check is for the namo command rather than for the gem, that being what the next step needs: an older namo installs no executable.
|
data/README.md
CHANGED
|
@@ -214,6 +214,8 @@ The `-:price` syntax uses unary minus on Symbol to produce a negated dimension.
|
|
|
214
214
|
sales[:product, -:price] # => ArgumentError
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
+
`-:price` is not a local trick: unary minus is defined on Symbol itself (`lib/Symbol.rb`), so once `namo` is loaded, every Symbol in the process has a `-@` it did not have before. Nothing in Ruby or its standard library reads a negated Symbol as anything — the ground was empty — so a collision would take another library claiming the same operator for its own purpose, and contraction is the part of Namo which yields if one does.
|
|
218
|
+
|
|
217
219
|
Selection and contraction can be chained:
|
|
218
220
|
|
|
219
221
|
```ruby
|
|
@@ -497,7 +499,7 @@ combined / fundamentals
|
|
|
497
499
|
|
|
498
500
|
The intersection of dimensions — here `:symbol` and `:pe` — is removed. Everything else stays. The projected rows are deduplicated, so `/` answers "what's left when these dimensions are factored out?" rather than "what rows survive a column drop?". Formulae carry through from the left-hand side.
|
|
499
501
|
|
|
500
|
-
`/` has no precondition. When the two Namos share no dimensions, the intersection is empty, nothing is removed, and `self / other` returns a Namo equal to self:
|
|
502
|
+
`/` has no precondition. When the two Namos share no dimensions, the intersection is empty, nothing is removed, and `self / other` returns a Namo equal to self (multiplicity aside — the deduplication above still applies, so "equal" here means equal on duplicate-free rows):
|
|
501
503
|
|
|
502
504
|
```ruby
|
|
503
505
|
shipments = Namo.new([{order_id: 1, weight: 10}])
|
|
@@ -507,7 +509,7 @@ shipments / weather
|
|
|
507
509
|
# => #<Namo [{order_id: 1, weight: 10}]> — equal to shipments
|
|
508
510
|
```
|
|
509
511
|
|
|
510
|
-
The round-trip identity holds for the `**` case exactly:
|
|
512
|
+
The round-trip identity holds for the `**` case exactly — again on duplicate-free rows, for the reason given below:
|
|
511
513
|
|
|
512
514
|
```ruby
|
|
513
515
|
a = Namo.new([{symbol: 'BHP'}, {symbol: 'RIO'}])
|
|
@@ -525,7 +527,7 @@ b = Namo.new([{symbol: 'BHP', pe: 14.5}, {symbol: 'RIO', pe: 9.2}])
|
|
|
525
527
|
|
|
526
528
|
(a * b) / b
|
|
527
529
|
# => #<Namo [{close: 42.5}, {close: 118.3}]>
|
|
528
|
-
# Equal to a[-:symbol]. :symbol was shared and is lost.
|
|
530
|
+
# Equal to a[-:symbol] on duplicate-free rows. :symbol was shared and is lost.
|
|
529
531
|
```
|
|
530
532
|
|
|
531
533
|
The asymmetry is inherent: `/` operates only on the two values it receives and can't distinguish "shared dimension that belonged to both" from "exclusive dimension that belonged only to the right". Removing the intersection is the only rule expressible from the operands alone, and it gives clean recovery from `**` and well-defined (if lossy) recovery from `*`.
|
|
@@ -534,14 +536,20 @@ The asymmetry is inherent: `/` operates only on the two values it receives and c
|
|
|
534
536
|
|
|
535
537
|
`*` and `**` raise when their preconditions are violated — combining unrelated Namos has no natural answer, and silently producing arbitrary output would turn a logic error into a large pile of nonsense rows. `/` is different: it's a projecting operator, not a combining one, and projecting away nothing returns the original. The no-precondition rule isn't a fallback; it's the structurally correct result.
|
|
536
538
|
|
|
537
|
-
This earns `/` three properties a strict version would lose:
|
|
539
|
+
This earns `/` three properties a strict version would lose, each stated for duplicate-free rows (the projection deduplicates; see below):
|
|
538
540
|
|
|
539
541
|
- **Identity test.** `combined / other == combined` exactly when the two have no shared dimensions — answers "are these Namos dimensionally independent?" without explicit introspection. Same shape as `a & b == a` answering subset from 0.6.0.
|
|
540
542
|
- **Idempotence.** `(c / b) / b == c / b`. Once `b`'s dimensions are removed, removing them again does nothing.
|
|
541
|
-
- **Pipeline composition.** A processing step that applies `/ separator` can run over any Namo regardless of whether the separator's dimensions apply. Uninvolved Namos pass through
|
|
543
|
+
- **Pipeline composition.** A processing step that applies `/ separator` can run over any Namo regardless of whether the separator's dimensions apply. Uninvolved Namos pass through stripped of nothing but duplicate rows; involved Namos get their shared dimensions stripped. The pipeline doesn't need to special-case applicability.
|
|
542
544
|
|
|
543
545
|
This is the same pattern that makes `Array#-` useful with arrays that aren't subsets: `[1, 2, 3] - [9] == [1, 2, 3]`, not an error. The no-op-on-non-applicable behaviour lets the operator compose into pipelines that don't know in advance whether the operation applies.
|
|
544
546
|
|
|
547
|
+
#### Why `/` dedupes
|
|
548
|
+
|
|
549
|
+
`/` is the one operator outside the set family (`&`, `|`, `^`) and the explicitly collapsing verbs (`uniq`, `coordinates`) that drops multiplicities — everywhere else duplicate rows are data. The collapse is definitional, and is in fact what makes `/` the inverse of the composers at all: `**` with a multi-row right operand manufactures multiplicities on the left operand's rows, so any projection that kept them could never satisfy `(a ** b) / b == a`. Inversion is only a function once duplicates are collapsed.
|
|
550
|
+
|
|
551
|
+
Projection with multiplicities intact is one line of existing operators: `namo[*other.data_dimensions.map{|d| -d}]` — contraction over the other operand's dimensions. `[]`, contraction, and everything else in the row algebra are bag-faithful, so nothing essential goes unspellable; what `/` alone adds over the contraction spelling is operand-keying plus the collapse, which is to say, its role as the composition algebra's decomposer.
|
|
552
|
+
|
|
545
553
|
### Equality
|
|
546
554
|
|
|
547
555
|
Comparison on Namos is **multiset-theoretic on rows**: the comparison operators — `==`, `eql?`, `===`, `<`, `<=`, `>`, `>=` — ignore row order, so two Namos holding the same rows in a different order compare equal, while row multiplicities count (they *are* data). That stance is shared across the equality, pattern-match, and subset/superset operators documented below. Row order is otherwise preserved: `to_h` and `values` depend on it for columnar alignment, and `each`, `first`, `last`, `take`, `drop`, and `+` all observe it. It is the comparison operators alone that treat the sequence of rows as a multiset.
|
data/lib/Namo/VERSION.rb
CHANGED
data/lib/namo.rb
CHANGED
|
@@ -306,9 +306,10 @@ class Namo
|
|
|
306
306
|
@name.nil? ? '' : " #{@name.inspect}"
|
|
307
307
|
end
|
|
308
308
|
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
309
|
+
# inspect is called for every result in a console, so evaluating the derived
|
|
310
|
+
# dimensions is bounded to the rows shown — INSPECTED_ROWS of them, one
|
|
311
|
+
# evaluation each — and a formula which raises renders no value rather than
|
|
312
|
+
# raising out of inspect. The cost is constant however large the data.
|
|
312
313
|
def inspected_rows(rendered)
|
|
313
314
|
return ' []' if @data.empty?
|
|
314
315
|
shown = rendered.map{|row, derived| " #{row.merge(derived).inspect}"}.join(",\n")
|
data/namo.gemspec
CHANGED
|
@@ -27,13 +27,13 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
spec.require_paths = ['lib']
|
|
28
28
|
|
|
29
29
|
spec.files = [
|
|
30
|
+
'namo.gemspec',
|
|
30
31
|
Dir['bin/*'],
|
|
31
32
|
Dir['lib/**/*.rb'],
|
|
32
33
|
Dir['test/**/*.rb'],
|
|
33
34
|
'CHANGELOG',
|
|
34
35
|
'Gemfile',
|
|
35
36
|
'LICENSE',
|
|
36
|
-
'namo.gemspec',
|
|
37
37
|
'Rakefile',
|
|
38
38
|
'README.md',
|
|
39
39
|
].flatten
|
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.32.
|
|
4
|
+
version: 0.32.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
105
105
|
- !ruby/object:Gem::Version
|
|
106
106
|
version: '0'
|
|
107
107
|
requirements: []
|
|
108
|
-
rubygems_version: 4.0.
|
|
108
|
+
rubygems_version: 4.0.21
|
|
109
109
|
specification_version: 4
|
|
110
110
|
summary: Named dimensional data for Ruby.
|
|
111
111
|
test_files: []
|