flexor 0.1.0 → 0.1.1
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/.rubocop.yml +23 -12
- data/CLAUDE.md +62 -0
- data/issues.rec +24 -0
- data/lib/f.rb +3 -0
- data/lib/flexor/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 957721d918f235f01e558af4a5303fd07a6e92ca70d0ef11b49d2fb58ea9ccfe
|
|
4
|
+
data.tar.gz: 32dd414daa542578908e01fd737f932a5a01ec886571bde813cf5634d82fe7e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a9082e8189768c8c073448fff223b1aaf3054d9474ac64faf8b3030fd27296c01d1f40a83356b69aa020e32b98ac4d2d0003f5eeebb8bd7652f98413033b9a4d
|
|
7
|
+
data.tar.gz: cef0d9d8d02589775c9361f21e00e494a208555c3048270ac937ebd995a834ab5a66d075c690404feeccbbd344c8a7ae1e37ca1161ef702676c5767ffbc6b359
|
data/.rubocop.yml
CHANGED
|
@@ -13,10 +13,9 @@ plugins:
|
|
|
13
13
|
- rubocop-claude
|
|
14
14
|
- rubocop-performance
|
|
15
15
|
- rubocop-rspec
|
|
16
|
-
- rubocop-md
|
|
17
|
-
- rubocop-rake
|
|
18
16
|
|
|
19
17
|
AllCops:
|
|
18
|
+
NewCops: enable
|
|
20
19
|
TargetRubyVersion: 3.4
|
|
21
20
|
|
|
22
21
|
# ===========================================================================
|
|
@@ -172,9 +171,6 @@ Style/RedundantReturn:
|
|
|
172
171
|
# ===========================================================================
|
|
173
172
|
# Overrides from rubocop-performance — disable chain-hostile cops
|
|
174
173
|
# ===========================================================================
|
|
175
|
-
Performance:
|
|
176
|
-
Exclude:
|
|
177
|
-
- "spec/**/*"
|
|
178
174
|
|
|
179
175
|
# ChainArrayAllocation flags idiomatic pipelines for microsecond gains.
|
|
180
176
|
# If we need real throughput we parallelize, not uglify.
|
|
@@ -233,12 +229,19 @@ Metrics/BlockLength:
|
|
|
233
229
|
- heredoc
|
|
234
230
|
- method_call
|
|
235
231
|
AllowedMethods:
|
|
232
|
+
- command
|
|
236
233
|
- describe
|
|
237
234
|
- context
|
|
238
235
|
- shared_examples
|
|
239
236
|
- shared_examples_for
|
|
240
237
|
- shared_context
|
|
241
238
|
|
|
239
|
+
# Shared test contexts legitimately define many helpers (stdin, stdout,
|
|
240
|
+
# stderr, env, cli, exit_status, output). These are a single fixture,
|
|
241
|
+
# not independent concerns.
|
|
242
|
+
RSpec/MultipleMemoizedHelpers:
|
|
243
|
+
Max: 10
|
|
244
|
+
|
|
242
245
|
# Anonymous forwarding (*, **, &) breaks TruffleRuby, JRuby, and
|
|
243
246
|
# Ruby < 3.2. Named args are explicit and portable.
|
|
244
247
|
#
|
|
@@ -379,16 +382,24 @@ RSpec/LeadingSubject:
|
|
|
379
382
|
RSpec/ExpectChange:
|
|
380
383
|
EnforcedStyle: block
|
|
381
384
|
|
|
382
|
-
|
|
385
|
+
# Disabled because OpenStruct is used for testing
|
|
386
|
+
Style/OpenStructUse:
|
|
383
387
|
Enabled: false
|
|
384
388
|
|
|
385
|
-
|
|
386
|
-
#
|
|
387
|
-
# Behavior is very intricate here and warrants separation
|
|
388
|
-
RSpec/SpecFilePathFormat:
|
|
389
|
+
RSpec/NamedSubject:
|
|
389
390
|
Enabled: false
|
|
390
391
|
|
|
392
|
+
# Would rather be as thorough as possible here as this is inherently a "not normally safe" library
|
|
391
393
|
RSpec/NestedGroups:
|
|
392
|
-
|
|
394
|
+
Max: 4
|
|
395
|
+
|
|
393
396
|
RSpec/MultipleExpectations:
|
|
394
|
-
Max:
|
|
397
|
+
Max: 2
|
|
398
|
+
|
|
399
|
+
# Prefer the explicit &block rather than &
|
|
400
|
+
Naming/BlockForwarding:
|
|
401
|
+
Enabled: false
|
|
402
|
+
|
|
403
|
+
# This has bugs and is causing specs to fail when autocorrected
|
|
404
|
+
Performance/RedundantMerge:
|
|
405
|
+
Enabled: false
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
1. DO NOT edit .rubocop.yml or add inline rubocop exemptions without explicit permission
|
|
8
|
+
2. DO NOT run any git command that will rewrite history without explicit permission
|
|
9
|
+
3. PREFER method & class extraction over comments
|
|
10
|
+
4. Making new files, classes, modules, and methods IS NOT overengineering
|
|
11
|
+
5. BEFORE writing code, identify which domain concept owns the behavior. Each class and module should have a single responsibility. If the new behavior doesn't fit an existing class's responsibility, create a new one — don't expand the scope of what's already there.
|
|
12
|
+
6. DO NOT name classes with suffixes like "-er" or "-or" unless using a canonical pattern name (e.g., Parser, Router, Controller)
|
|
13
|
+
7. ALWAYS write specs first. The workflow is: identify the domain concept (rule 5), write specs describing its behavior, then implement. No implementation without a failing spec.
|
|
14
|
+
|
|
15
|
+
## Project
|
|
16
|
+
|
|
17
|
+
Flexor is a Ruby gem providing a Hash-like data store with autovivifying nested access, nil-safe chaining, and seamless conversion between hashes and method-style access. Requires Ruby >= 3.4.
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
- `rake spec` — run all tests
|
|
22
|
+
- `bundle exec rspec spec/flexor/flexor_reading_spec.rb` — run a single spec file
|
|
23
|
+
- `bundle exec rspec spec/flexor/flexor_reading_spec.rb:15` — run a single example by line
|
|
24
|
+
- `rake rubocop` — run linter
|
|
25
|
+
- `bundle exec rubocop -a` — autocorrect safe offenses
|
|
26
|
+
- `rake` — run both specs and rubocop (default task)
|
|
27
|
+
- `rake benchmark` — run performance benchmarks (uses YJIT)
|
|
28
|
+
- `rake rdoc` — generate documentation
|
|
29
|
+
- `rake version:current` — show current version
|
|
30
|
+
- `rake version:bump` — bump patch version
|
|
31
|
+
- `bin/console` — IRB session with Flexor loaded
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
Single class `Flexor` in `lib/flexor.rb` with three mixins:
|
|
36
|
+
|
|
37
|
+
- **`Vivification`** (`lib/flexor/vivification.rb`) — recursively converts Hashes/Arrays into Flexor objects on write; reverses via `recurse_to_h` on read. The `@store` uses a `Hash.new` default block that auto-creates child Flexor nodes (autovivification).
|
|
38
|
+
- **`HashDelegation`** (`lib/flexor/hash_delegation.rb`) — delegates `keys`, `values`, `size`, `empty?`, `key?` to `@store`.
|
|
39
|
+
- **`Serialization`** (`lib/flexor/serialization.rb`) — Marshal and YAML round-trip support.
|
|
40
|
+
|
|
41
|
+
Key internals:
|
|
42
|
+
- `@store` is the backing Hash with an autovivifying default block
|
|
43
|
+
- `@root` flag distinguishes top-level instances from auto-created children (affects `inspect` and `nil?` behavior)
|
|
44
|
+
- `method_missing` handles dynamic getter/setter; once accessed, singleton methods are cached for performance (`cache_getter`/`cache_setter`)
|
|
45
|
+
- `nil?` returns `true` when `@store` is empty (non-root nodes appear nil-like until written to)
|
|
46
|
+
|
|
47
|
+
## Style Conventions (from .rubocop.yml)
|
|
48
|
+
|
|
49
|
+
- Double quotes always (`Style/StringLiterals`)
|
|
50
|
+
- No frozen_string_literal comments
|
|
51
|
+
- Trailing commas in multiline literals/arguments
|
|
52
|
+
- Pipeline-style chaining encouraged (multiline block chains allowed)
|
|
53
|
+
- Block length max 8 (keeps blocks small, push logic into pipelines)
|
|
54
|
+
- Dot-aligned chaining (`Layout/MultilineMethodCallIndentation: aligned`)
|
|
55
|
+
- Consistent 2-space argument indentation (not aligned to first arg)
|
|
56
|
+
- Explicit `begin/rescue/end` preferred over implicit method-body rescue
|
|
57
|
+
- All classes require rdoc documentation (`Style/Documentation`)
|
|
58
|
+
- RSpec: `expect { }.to change { }` block style, nested groups max 4, multiple expectations max 2
|
|
59
|
+
|
|
60
|
+
## Tests
|
|
61
|
+
|
|
62
|
+
Specs are organized by concern in `spec/flexor/` (reading, writing, merge, serialization, freeze, etc.). The top-level `spec/flexor_spec.rb` only checks the version. RSpec runs with `--format documentation` and monkey patching disabled.
|
data/issues.rec
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
%rec: Issue
|
|
2
|
+
%key: Id
|
|
3
|
+
%typedef: Status_t enum open in_progress closed
|
|
4
|
+
%typedef: Description_t regexp /.*/
|
|
5
|
+
%type: Id uuid
|
|
6
|
+
%type: Title line
|
|
7
|
+
%type: Description Description_t
|
|
8
|
+
%type: Updated date
|
|
9
|
+
%type: Status Status_t
|
|
10
|
+
%auto: Id Updated
|
|
11
|
+
|
|
12
|
+
Id: BAA28228-220B-11F1-88B7-FE6CB9572C2E
|
|
13
|
+
Updated: Tue, 17 Mar 2026 10:15:19 -0400
|
|
14
|
+
Title: Add constant F that is set equal to Flexor
|
|
15
|
+
Description: As Flexor is built to maximize ergonomics, it would be ideal to have a shorter way to call it. In lib, there should be f.rb, where F = Flexor as the only line. It could be called like:
|
|
16
|
+
+ puts F[json_string].people.first.first_name
|
|
17
|
+
+
|
|
18
|
+
Status: open
|
|
19
|
+
|
|
20
|
+
Id: A4C9FDF4-2220-11F1-BED9-FE6CB9572C2E
|
|
21
|
+
Updated: Tue, 17 Mar 2026 12:45:02 -0400
|
|
22
|
+
Title: Address rubocop offenses
|
|
23
|
+
Description: Currently 30 violations as I write this
|
|
24
|
+
Status: open
|
data/lib/f.rb
ADDED
data/lib/flexor/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flexor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Gillis
|
|
@@ -21,6 +21,7 @@ files:
|
|
|
21
21
|
- ".rspec"
|
|
22
22
|
- ".rubocop.yml"
|
|
23
23
|
- ".ruby-version"
|
|
24
|
+
- CLAUDE.md
|
|
24
25
|
- LICENSE.txt
|
|
25
26
|
- README.md
|
|
26
27
|
- Rakefile
|
|
@@ -29,6 +30,8 @@ files:
|
|
|
29
30
|
- docs/benchmark-results.md
|
|
30
31
|
- docs/original_specification.yaml
|
|
31
32
|
- docs/specification.yaml
|
|
33
|
+
- issues.rec
|
|
34
|
+
- lib/f.rb
|
|
32
35
|
- lib/flexor.rb
|
|
33
36
|
- lib/flexor/hash_delegation.rb
|
|
34
37
|
- lib/flexor/serialization.rb
|
|
@@ -58,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
58
61
|
- !ruby/object:Gem::Version
|
|
59
62
|
version: '0'
|
|
60
63
|
requirements: []
|
|
61
|
-
rubygems_version: 4.0.
|
|
64
|
+
rubygems_version: 4.0.7
|
|
62
65
|
specification_version: 4
|
|
63
66
|
summary: A Hash-like data store that does what you tell it to do
|
|
64
67
|
test_files: []
|