Revision history for LTSV::LINQ
1.07 2026-03-25 JST (Japan Standard Time)
Tests:
- Added t/lib/INA_CPAN_Check.pm: shared test library providing
TAP harness, file utilities, MANIFEST helpers, version/META
parsers, code scanner, and check_A through check_K
implementations (aligned with DB-Handy 1.07 and HTTP-Handy 1.03).
- Added t/9001-load.t: module load, $VERSION, LTSV::LINQ::Ordered
sub-package, all public methods (From/Where/Select/etc.),
and INA_CPAN_Check library export verification.
- Added t/9010-encoding.t: US-ASCII, trailing whitespace, and
end-of-file newline checks (replaces t/0010-usascii.t).
- Added t/9020-perl5compat.t: Perl 5.005_03 syntax checks P1-P14
covering .pm, .t, and eg/*.pl (replaces t/0015-perl5compat.t;
adds P13 @-/@+ prohibition and P14 header order check).
- Added t/9030-distribution.t: MANIFEST, version consistency,
META integrity, Changes format, Makefile.PL, and test-suite
consistency (replaces t/0016-cpan_precheck.t categories A-J).
- Added t/9040-style.t: coding style E and K checks
(replaces t/0016-cpan_precheck.t categories E/K and
t/0014-style.t).
- Added t/9050-pod.t: POD structure/content G1-G11 including
VERSION format, TABLE OF CONTENTS completeness, DIAGNOSTICS
coverage, and Pod::Checker syntax check.
- Added t/9060-readme.t: README required sections check.
- Added t/9070-examples.t: eg/ script quality E1-E6
(no shebang, CVE fix, FindBin, boilerplate order,
filename comment, Demonstrates section with method verification).
- Added t/9080-cheatsheets.t: doc/ cheat sheet native script,
section numbering, and [XX] header tag checks.
- Removed t/0010-usascii.t: superseded by t/9010-encoding.t.
- Removed t/0014-style.t: superseded by t/9040-style.t.
- Removed t/0015-perl5compat.t: superseded by t/9020-perl5compat.t.
- Removed t/0016-cpan_precheck.t: superseded by t/9030-t/9080.
Fixes:
- lib/LTSV/LINQ.pm: warnings stub now guards with
!defined(&warnings::import) to suppress "import redefined"
warnings when multiple modules are loaded in sequence.
- lib/LTSV/LINQ.pm: return \%record / \%dictionary / \%lookup
changed to return { %record } / { %dictionary } / { %lookup }
(K3 coding style: use { %hash } form for hash references).
- lib/LTSV/LINQ.pm: DIAGNOSTICS =item for "Cannot open" error
corrected to E<lt>filenameE<gt>: E<lt>reasonE<gt> form so that
the G10 DIAGNOSTICS-coverage check passes.
1.06 2026-03-23 JST (Japan Standard Time)
Coding style aligned with DB-Handy and HTTP-Handy:
- Module header: added Compatible/Platform comment block.
- use strict/warnings order unified: use strict -> BEGIN{warnings stub}
-> use warnings; local $^W = 1; -> BEGIN { pop @INC } (DB-Handy style).
- $VERSION declared via use vars (aligned with DB-Handy/HTTP-Handy style).
- Section separators changed from # ---...--- (65 chars) to
###...### (79 chars) matching DB-Handy and HTTP-Handy.
- pmake.bat: install target now greps lib/**/*.pm only (DB-Handy style).
Code style fixes (K-category):
- K1: comma-space: my($s,$k) -> my($s, $k) in ThenBy* methods.
- K2: \@items -> [ @items ] where passed as argument (OrderBy*, Reverse,
GroupJoin).
- K3: return \%hash exempted; no other \%hash violations in code.
Test suite improvements (knowledge from DB-Handy and HTTP-Handy):
Naming and style:
- Renamed test files to 4-digit zero-padded hyphen format
(001_basic.t -> 0001-basic.t, etc.).
- Rewrote all functional test harnesses to DB-Handy/HTTP-Handy style:
use strict, BEGIN{warnings stub}, BEGIN{pop @INC}, use FindBin / use lib,
($PASS, $FAIL, $T) variables, 1-line ok/is/like subs,
print "1..N\n" plan, exit($FAIL ? 1 : 0) at end.
- Removed shebang line (#!/usr/bin/perl) from t/0014-style.t.
New test files:
- t/0010-usascii.t: US-ASCII check for all MANIFEST files (replaces
t/010_ascii_only.t which only checked lib/LTSV/LINQ.pm); doc/ files
exempt (UTF-8 cheat sheets).
- t/0015-perl5compat.t: Perl 5.005_03 compatibility checks (P1-P12)
covering forbidden keywords, operators, VERSION self-assignment,
warnings stub, and CVE-2016-1238 mitigation.
- t/0016-cpan_precheck.t: comprehensive pre-publication check suite
(categories A-K, 240 tests) ported from HTTP-Handy; covers file
structure, version consistency, encoding, compatibility, style, META
integrity, POD completeness, Changes format, and Makefile.PL;
eg/*.pl included in C/E style checks.
Samples and documentation:
- eg/01_ltsv_query.pl: LTSV file query with FromLTSV/Where/Select/
OrderByNumDescending/Distinct/ToLookup.
- eg/02_array_query.pl: in-memory array queries, aggregation,
Any/All, Skip/Take paging, Zip.
- eg/03_grouping.pl: GroupBy, ToLookup, GroupJoin (left outer join),
SelectMany with array-ref selector.
- eg/04_sorting.pl: OrderBy/ThenBy multi-key sort, OrderByNum vs
OrderByStr, Reverse.
- doc/linq_cheatsheet.*.txt: LTSV::LINQ cheat sheets in 21 languages
covering query creation, filtering, projection, sorting, grouping,
set operations, joins, aggregation, and official spec links.
- README: rewritten to DB-Handy/HTTP-Handy structure with NAME,
SYNOPSIS, DESCRIPTION, INCLUDED DOCUMENTATION, INSTALLATION,
COMPATIBILITY (Perl 5.005_03 philosophy), TARGET USE CASES,
LIMITATIONS, AUTHOR, and COPYRIGHT AND LICENSE.
Documentation fixes:
- POD =head1 VERSION: corrected from "Version 1.05" to "Version 1.06".
- POD TABLE OF CONTENTS: added missing sections (INCLUDED DOCUMENTATION,
DESIGN PHILOSOPHY, LIMITATIONS AND KNOWN ISSUES, BUGS, SUPPORT);
removed phantom entry (Data Source Methods is =head2, not =head1)
and non-standard entries (AUTHOR, COPYRIGHT AND LICENSE).
- POD: added =head1 INCLUDED DOCUMENTATION section listing eg/ and
doc/ files (aligned with DB-Handy and HTTP-Handy).
- POD DIAGNOSTICS: added four missing die-message entries:
"Sequence contains more than one element" (Single),
"Index must be non-negative" and "Index out of range" (ElementAt),
"Invalid number of arguments for Aggregate" (Aggregate).
- POD DIAGNOSTICS: added full =item C<...> entries with description
and examples for all four new die messages.
- README and eg/01_ltsv_query.pl: corrected method name
FromFile -> FromLTSV (FromFile does not exist).
- eg/01_ltsv_query.pl: removed shebang (#!/usr/bin/perl); added
OrderBy to Demonstrates (used in code but previously unlisted).
- eg/02_array_query.pl: added Contains example to match Demonstrates
comment; corrected Demonstrates to include OrderByNumDescending;
added ToArray to Demonstrates.
- eg/03_grouping.pl: removed shebang; added Select, Sum, OrderBy,
Distinct, ToArray to Demonstrates (all used in code).
- eg/04_sorting.pl: removed shebang; corrected Demonstrates to match
actual usage (removed OrderByDescending, ThenBy, ThenByDescending
which are not used; added ThenByNumDescending, ThenByStr).
- doc/linq_cheatsheet.*.txt: all 21 language cheat sheets rewritten
with complete method coverage (60 methods, sections [1..12]);
section 11 "Conversion methods" added (ToDictionary, ToLookup,
ToLTSV, ToList); corrected Append/Prepend phantom entries removed;
non-ASCII native scripts used for KO, ZH, TW, JA, TH, HI, BN,
MY, KM, MN, NE, SI, UR (aligned with DB-Handy style).
1.05 2026-02-23 JST (Japan Standard Time)
Perl 5.005_03 compatibility fixes:
- warnings stub: added "package warnings; sub import {}" to the BEGIN
block so that "use warnings" does not fail with
"Can't locate object method 'import'" on Perl 5.005_03.
Previously only $INC{'warnings.pm'} was set, which suppresses
the file-load but not the method call.
Correctness fix:
- ToLTSV: sanitize record values before writing. Values containing
tab (\t), carriage return (\r), or newline (\n) are now mapped
to a single space, preventing structural corruption of the LTSV
output. FromLTSV round-trips are now safe for any record value.
Also handles undef values (written as empty string).
Code quality:
- Removed trailing whitespace from 24 lines (code and POD).
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