namo 0.32.3 → 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 +20 -8
- data/README.md +43 -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,7 +1,27 @@
|
|
|
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
|
|
|
17
|
+
0.32.4: ~ README.md: + Console, the command the gem has shipped since 0.32.0 going unmentioned until now.
|
|
18
|
+
|
|
19
|
+
1. ~ README.md: + Console. `namo console` and `namo setup` had appeared nowhere: the gem gained an executable at 0.32.0 and the README named install.sh once, in the curl line, and the command not at all. Someone taking `gem install namo`, the first line of Installation, arrived at the library without learning that the console existed.
|
|
20
|
+
2. ~ README.md: + the clone route, `git clone` and ./install.sh, which is the route the adjacent-bin/namo handover of 0.32.3 was written for and the one route no line described.
|
|
21
|
+
3. ~ README.md: `gem install` and the Gemfile line say what they leave undone — the command is on the PATH only where gem's own directory is, which Homebrew's Ruby is the case against, and measurand arrives by `namo setup` rather than with the gem, a gemspec having no way to name a companion which is optional.
|
|
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.
|
|
23
|
+
5. ~ Namo::VERSION: /0.32.3/0.32.4/
|
|
24
|
+
|
|
5
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.
|
|
6
26
|
|
|
7
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.
|
|
@@ -12,9 +32,6 @@
|
|
|
12
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.
|
|
13
33
|
7. ~ Namo::VERSION: /0.32.2/0.32.3/
|
|
14
34
|
|
|
15
|
-
|
|
16
|
-
## 20260828
|
|
17
|
-
|
|
18
35
|
0.32.2: ~ install.sh: the one command ends with namo runnable from anywhere.
|
|
19
36
|
|
|
20
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.
|
|
@@ -23,9 +40,6 @@
|
|
|
23
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.
|
|
24
41
|
5. ~ Namo::VERSION: /0.32.1/0.32.2/
|
|
25
42
|
|
|
26
|
-
|
|
27
|
-
## 20260828
|
|
28
|
-
|
|
29
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.
|
|
30
44
|
|
|
31
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.
|
|
@@ -35,8 +49,6 @@
|
|
|
35
49
|
5. ~ Namo::VERSION: /0.32.0/0.32.1/
|
|
36
50
|
|
|
37
51
|
|
|
38
|
-
## 20260828
|
|
39
|
-
|
|
40
52
|
0.32.0: + bin/namo, the gem's first executable, and the gems it installs.
|
|
41
53
|
|
|
42
54
|
1. + bin/namo: a setup subcommand which installs the gems Namo's scripts want — Namo itself, so that a clone leaves require 'namo' working, and measurand, which the demo's uncertainty section does without when it is missing — and a console subcommand which is bin/console. Each step asks first and says so when there is nothing to do.
|
data/README.md
CHANGED
|
@@ -18,12 +18,42 @@ Or in your Gemfile:
|
|
|
18
18
|
gem 'namo'
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
Either brings the `namo` command with it, where the directory gem installs commands into is one your PATH reaches — it is on a Ruby from ruby-install or rbenv, and is not on Homebrew's. `namo setup` then adds measurand, which the uncertainty examples want and which nothing else does.
|
|
22
|
+
|
|
23
|
+
Or from a clone, which wants none of it installed first:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
git clone https://github.com/thoran/namo.git
|
|
27
|
+
cd namo
|
|
28
|
+
./install.sh
|
|
29
|
+
```
|
|
30
|
+
|
|
21
31
|
Or from nothing at all — Ruby, the gem, and the gems its scripts want, each step skipped where it is already there. Where Ruby is missing, whichever package manager is already installed supplies it — Homebrew, MacPorts, apt, dnf, pacman or zypper; where none is, you are asked before Homebrew is installed, and then before ruby-install is built from source; `-y` answers yes in advance, and a machine with nobody at the keyboard is taken to have said no. Where the gem's own directory is not on the PATH, it offers to add it to your shell's configuration, so that a new shell has `namo` in it:
|
|
22
32
|
|
|
23
33
|
```
|
|
24
34
|
sh -c "$(curl -fsSL https://raw.githubusercontent.com/thoran/namo/master/install.sh)"
|
|
25
35
|
```
|
|
26
36
|
|
|
37
|
+
The two which run `install.sh` end at a `namo` which runs from anywhere. The first ends at one which runs where your PATH already reaches it.
|
|
38
|
+
|
|
39
|
+
## Console
|
|
40
|
+
|
|
41
|
+
The gem ships one command.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
namo console
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
An irb session with Namo loaded, for asking a question of the library without writing a file first.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
namo setup
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Installs the gems the scripts want — namo itself, and measurand — skipping whichever is already there and naming each and its version either way. `install.sh` runs it as the last of its own work, so it is here for a gem which arrived by `gem install`, and for adding measurand to an installation which went without it.
|
|
54
|
+
|
|
55
|
+
`namo` alone prints the usage, as `namo --help` does.
|
|
56
|
+
|
|
27
57
|
## Usage
|
|
28
58
|
|
|
29
59
|
Create a Namo instance from an array of hashes:
|
|
@@ -184,6 +214,8 @@ The `-:price` syntax uses unary minus on Symbol to produce a negated dimension.
|
|
|
184
214
|
sales[:product, -:price] # => ArgumentError
|
|
185
215
|
```
|
|
186
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
|
+
|
|
187
219
|
Selection and contraction can be chained:
|
|
188
220
|
|
|
189
221
|
```ruby
|
|
@@ -467,7 +499,7 @@ combined / fundamentals
|
|
|
467
499
|
|
|
468
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.
|
|
469
501
|
|
|
470
|
-
`/` 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):
|
|
471
503
|
|
|
472
504
|
```ruby
|
|
473
505
|
shipments = Namo.new([{order_id: 1, weight: 10}])
|
|
@@ -477,7 +509,7 @@ shipments / weather
|
|
|
477
509
|
# => #<Namo [{order_id: 1, weight: 10}]> — equal to shipments
|
|
478
510
|
```
|
|
479
511
|
|
|
480
|
-
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:
|
|
481
513
|
|
|
482
514
|
```ruby
|
|
483
515
|
a = Namo.new([{symbol: 'BHP'}, {symbol: 'RIO'}])
|
|
@@ -495,7 +527,7 @@ b = Namo.new([{symbol: 'BHP', pe: 14.5}, {symbol: 'RIO', pe: 9.2}])
|
|
|
495
527
|
|
|
496
528
|
(a * b) / b
|
|
497
529
|
# => #<Namo [{close: 42.5}, {close: 118.3}]>
|
|
498
|
-
# 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.
|
|
499
531
|
```
|
|
500
532
|
|
|
501
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 `*`.
|
|
@@ -504,14 +536,20 @@ The asymmetry is inherent: `/` operates only on the two values it receives and c
|
|
|
504
536
|
|
|
505
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.
|
|
506
538
|
|
|
507
|
-
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):
|
|
508
540
|
|
|
509
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.
|
|
510
542
|
- **Idempotence.** `(c / b) / b == c / b`. Once `b`'s dimensions are removed, removing them again does nothing.
|
|
511
|
-
- **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.
|
|
512
544
|
|
|
513
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.
|
|
514
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
|
+
|
|
515
553
|
### Equality
|
|
516
554
|
|
|
517
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: []
|