Revision history for LTSV::LINQ
1.04 2026-02-21 JST (Japan Standard Time)
New methods (6):
- ThenBy($key_selector)
Add ascending secondary sort key (smart comparison) to an
LTSV::LINQ::Ordered sequence. Returns a new Ordered object.
- ThenByDescending($key_selector)
Add descending secondary sort key (smart comparison).
- ThenByStr($key_selector)
Add ascending secondary sort key (string/cmp comparison).
- ThenByStrDescending($key_selector)
Add descending secondary sort key (string/cmp comparison).
- ThenByNum($key_selector)
Add ascending secondary sort key (numeric/<=>) comparison).
Undefined or empty values treated as 0.
- ThenByNumDescending($key_selector)
Add descending secondary sort key (numeric/<=>) comparison).
Architecture:
- OrderBy* methods now return LTSV::LINQ::Ordered (subclass of
LTSV::LINQ via @ISA), mirroring .NET LINQ's IOrderedEnumerable<T>.
All existing LTSV::LINQ methods (Where, Select, Take, ...) are
available through inheritance. ThenBy* are only on Ordered objects.
- Sorting uses Schwartzian-Transform decorated-array with original-
element index as a final tie-breaker, guaranteeing completely stable
multi-key sorting on all Perl versions including 5.005_03.
- ThenBy* is non-destructive: each call returns a new Ordered object;
the original is unchanged, so branching sort chains are safe.
- Ordered objects are re-iterable (use _factory internally).
Documentation:
- Ordering Methods: section rewritten to cover ThenBy* family,
IOrderedEnumerable analogy, stability guarantee, non-destructive
semantics, and comparison-type families extended to include ThenBy*.
- Method Summary Table: OrderBy* Returns column updated to OrderedQuery;
ThenBy* rows added; footnote added explaining OrderedQuery.
- Not Implemented / Compound Ordering: ThenBy* entry updated from
"not implemented / workaround" to "implemented in v1.04".
- Method count: 54 -> 60.
Kwalitee fixes (for v1.03 issues reported by CPANTS):
- META.json: removed top-level 'minimum_perl_version' key (not valid in
CPAN::Meta::Spec v2; custom keys must begin with 'x_' or 'X_').
Perl version requirement is already expressed correctly via
prereqs.runtime.requires.perl. META.yml retains the key (valid
in META.yml spec v1.4).
- SECURITY.md: new file added (satisfies has_security_doc and
security_doc_contains_contact Kwalitee indicators).
Contains vulnerability reporting address ina@cpan.org.
- pmake.bat: updated to generate SECURITY.md and to omit
minimum_perl_version from the META.json template.
Tests:
- t/013_v104_thenby.t: new file, 42 tests.
Covers: return type (LTSV::LINQ::Ordered), ThenBy/ThenByDescending,
three-key sort, stability, non-destructive branching,
OrderByDescending + ThenBy, smart vs Str vs Num for ThenBy,
ThenByNum undef, ThenByNumDescending, ThenByStrDescending,
chaining with Where/Select/Count/First/Last/Take/Skip,
empty/single-element sequences, re-iterability, LTSV scenario.
- Total: 258 -> 300 tests across 13 files.
1.03 2026-02-20 JST (Japan Standard Time)
New methods (6):
- Join($inner, $outer_key, $inner_key, $result)
Inner join; inner sequence is fully buffered at call time.
- GroupJoin($inner, $outer_key, $inner_key, $result)
Left outer join; inner sequence fully buffered.
Inner group passed to result_selector as a re-iterable
LTSV::LINQ object (supports Count, Sum, Any, Where, etc.
called multiple times on the same group).
- OrderByStr($key_selector)
Sort ascending using string comparison (cmp) unconditionally.
- OrderByStrDescending($key_selector)
Sort descending using string comparison (cmp) unconditionally.
- OrderByNum($key_selector)
Sort ascending using numeric comparison (<=>) unconditionally.
Undefined keys treated as 0.
- OrderByNumDescending($key_selector)
Sort descending using numeric comparison (<=>) unconditionally.
Behavioural changes:
- GroupBy: groups are now returned in insertion order (first-seen key),
matching .NET LINQ behaviour. Previously sorted alphabetically.
- SelectMany: selector must now return an ARRAY reference; returning any
other type dies with "SelectMany: selector must return an ARRAY
reference". Previously non-ARRAY values were passed through
silently (behaving like Select).
- Distinct: without a key_selector, hash references and array references
are now compared by content (via internal _make_key), consistent
with Intersect and Except. Previously compared by reference
address (stringification), so structurally equal hashrefs were
not deduplicated.
- iterator(): enhanced to support _factory-based re-iteration, enabling
GroupJoin inner groups to be iterated multiple times.
- FirstOrDefault / LastOrDefault: fixed critical bug where a single
non-CODE argument was treated as a predicate, causing a crash.
A scalar argument is now correctly used as the default value.
- LastOrDefault: added optional $default argument to match the
FirstOrDefault([$predicate,] $default) signature.
Documentation:
- ARCHITECTURE: Method Categories replaced by a 54-row
Lazy/Materialising table (Evaluation + Returns columns).
- ARCHITECTURE: Memory Characteristics updated to match the table.
- COMPATIBILITY: new ".NET LINQ Compatibility" section listing exact
matches and intentional differences (SingleOrDefault, DefaultIfEmpty,
OrderBy smart comparison, EqualityComparer, query syntax).
- Ordering Methods: section header added explaining stable sort
(Perl 5.8+ guarantee) and the three comparison families.
- Set Operations: section header documenting partially-eager evaluation
(second sequence buffered at call time).
- Join Operations: section header documenting partially-eager evaluation
(inner sequence buffered at call time).
- GroupBy: note updated: "insertion order" replacing "sorted key order".
- LIMITATIONS: "GroupBy Sorts Keys" entry removed (no longer true).
- FromLTSV: file-handle management note added.
- Where DSL: explicit note that arguments must be even-count key=>value pairs.
- COOKBOOK: two new patterns: "Iterator consumption / snapshot" and
"Efficient large-file pattern".
- SelectMany: Important note updated to reflect die behaviour.
- DIAGNOSTICS: new entry "SelectMany: selector must return an ARRAY
reference"; FromLTSV entry expanded with file-handle note.
- DESIGN PHILOSOPHY: new section (Perl 5.005_03 compatibility rationale,
US-ASCII only policy, $VERSION idiom, design principles).
- Method count: 50 -> 54.
Tests:
- t/004_grouping.t: 8 tests -> 16 tests.
Added: GroupBy insertion order (3 tests),
Distinct content-equality for hashrefs/arrayrefs (5 tests).
- t/005_complex.t: 10 tests -> 14 tests.
Added: SelectMany dies on non-ARRAY return (2 tests),
SelectMany empty/mixed arrayref (2 tests).
- t/012_v103_ordering.t: new file, 40 tests.
Covers OrderByStr, OrderByStrDescending, OrderByNum,
OrderByNumDescending; stable sort; smart vs Str vs Num contrast;
LTSV realistic scenarios; edge cases.
- Total: 246 -> 258 tests across 12 files.
1.02 2026-02-17 JST (Japan Standard Time)
- Added 6 new methods for relational operations and utilities
New methods:
- Data sources: Empty, Repeat
- Concatenation: Zip
- Join operations: Join
- Conversion: ToDictionary, ToLookup
Improvements:
- Enhanced POD documentation with detailed examples
- Updated method summary table (45 -> 49 methods)
- Ensured all source code is US-ASCII only (no multibyte characters)
- Added test for ASCII-only verification
- Method count: 49 methods across 15 categories
1.01 2026-02-16 JST (Japan Standard Time)
- Added 14 new methods to enhance LINQ compatibility
New methods:
- Element access: LastOrDefault, Single, SingleOrDefault,
ElementAt, ElementAtOrDefault
- Quantifier: Contains
- Concatenation: Concat
- Partitioning: SkipWhile
- Default value: DefaultIfEmpty
- Aggregation: Aggregate
- Set operations: Union, Intersect, Except
- Comparison: SequenceEqual
Improvements:
- Enhanced POD documentation for all new methods
- Added comprehensive examples for each method
- Updated method summary table (31 -> 45 methods)
- Improved test coverage
- Optimized Single/ElementAt to use lazy evaluation (O(1) memory)
- Fixed Makefile.PL version inconsistency
- Clarified Perl 5.005_03 specification philosophy
- Added .NET LINQ compatibility notes
1.00 2026-02-15 JST (Japan Standard Time)
- Initial release
- LINQ-style query interface for LTSV files
- Inspired by Microsoft's LINQ (Language Integrated Query)
- LINQ(R) is a registered trademark of Microsoft Corporation
- Lazy evaluation with iterators
- DSL syntax for simple filtering (Where(key => value))
- Full method chaining support
- Compatible with Perl 5.005_03 and later
- Pure Perl implementation (no XS required)
Methods implemented:
- Data source: From, FromLTSV, Range
- Filtering: Where (with DSL)
- Projection: Select, SelectMany
- Partitioning: Take, Skip, TakeWhile
- Ordering: OrderBy, OrderByDescending, Reverse
- Grouping: GroupBy
- Set operations: Distinct
- Quantifiers: All, Any
- Element access: First, FirstOrDefault, Last
- Aggregation: Count, Sum, Min, Max, Average, AverageOrDefault
- Conversion: ToArray, ToList, ToLTSV
- Utility: ForEach