@@ -1789,53 +1789,61 @@ This happens partly because of the
1789
1789
L < single argument rule|/language/functions#Slurpy_Conventions > , and
1790
1790
there are other cases when this kind of a generalization may not work.
1791
1791
1792
- = head2 Beware of empty lists (and any other kind of element) when concatenating Bufs or Blobs.
1793
1792
1794
- The L < C < ~ > infix operator|/routine/~#(Operators)_infix_~> can be used to
1795
- concatenate L < Buf > s or L < Blob > s; we can then use this reduction operator in this
1796
- form:
1793
+ = head2 Using [~] for concatenating a list of Blobs
1797
1794
1798
- say [~] Buf.new(0x3, 0x33), Blob.new(0x2,0x22); # OUTPUT: «Buf:0x<03 33 02 22>»
1795
+ The L < C < ~ > infix operator|/routine/~#(Operators)_infix_~> can be used
1796
+ to concatenate L < Str > s I < or > L < Blob > s. However, an empty list will
1797
+ I < always > be reduced to an empty C < Str > . This is due to the fact that,
1798
+ in the presence of a list with no elements, the
1799
+ L < reduction|/language/operators#Reduction_Operators > metaoperator
1800
+ returns the
1801
+ L < identity element|https://en.wikipedia.org/wiki/Identity_element >
1802
+ for the given operator. Identity element for C < ~ > is an empty string,
1803
+ regardless of the kind of elements the list could be populated with.
1799
1804
1800
- However, an empty array will I < always > be reduced to an empty C < Str > :
1805
+ = for code
1806
+ my Blob @chunks;
1807
+ say ([~] @chunks).perl; # OUTPUT: «""»
1801
1808
1802
- my @bufs;
1803
- say [~] @bufs; # OUTPUT: «»
1804
- my Buf @buffs;
1805
- say [~] @buffs; # OUTPUT: «»
1806
1809
1807
- This is due to the fact that, in the presence of a list with no elements, the
1808
- reduction operator applies the C < identity > for the operator used to reduce, C < ~ >
1809
- in this case. And this results in an empty string, independently of the kind of
1810
- elements the list could be populated with.
1810
+ This might cause a problem if you attempt to use the result while
1811
+ assuming that it is a Blob:
1811
1812
1812
- my Int @bufs;
1813
- say [~] @bufs; # OUTPUT: «»
1813
+ = for code :skip-test<Documenting the error>
1814
+ my Blob @chunks;
1815
+ say ([~] @chunks).decode;
1816
+ # OUTPUT: «No such method 'decode' for invocant of type 'Str'. Did you mean 'encode'?…»
1814
1817
1815
- This might cause a problem if an empty list enters in a situation where you are
1816
- concatenating buffers (for instance, reading from an empty file):
1817
1818
1818
- = for code :skip-test<Documenting the error >
1819
- my @array-of-arrays= [[], [Buf.new(0x2, 0x22), Buf.new( 0x3, 0x33)]];
1820
- my @bufs;
1821
- for @array-of-arrays -> @a {
1822
- @bufs = [~] |@bufs, | @a ;
1823
- }
1824
- # OUTPUT: «(exit code 1) Cannot use a Buf as a string, but you called the Stringy method on it »
1819
+ There are many ways to cover that case. You can avoid C < [ ] >
1820
+ metaoperator altogether:
1821
+
1822
+ = for code
1823
+ my @chunks ;
1824
+ # …
1825
+ say Blob.new: |«@chunks; # OUTPUT: «Blob:0x<> »
1825
1826
1826
- In the code above, the first element of C < @array-of-array > will be reduced to an
1827
- empty string, causing the error when entering the second iteration.
1828
1827
1829
- So if you want to avoid this problem with L < Buf > s, initialize the array with an
1830
- empty element.
1828
+ Alternatively, you can initialize the array with an empty Blob:
1831
1829
1832
- my Buf @buffs = Buf.new;
1833
- say [~] @buffs; # OUTPUT: «Buf:0x<>»
1830
+ = for code
1831
+ my @chunks = Blob.new;
1832
+ # …
1833
+ say [~] @chunks; # OUTPUT: «Blob:0x<>»
1834
+
1835
+
1836
+ Or you can utilize L < C < || > |#infix || > operator to make it use an
1837
+ empty Blob in case the list is empty:
1838
+
1839
+ = for code
1840
+ my @chunks;
1841
+ # …
1842
+ say [~] @chunks || Blob.new; # OUTPUT: «Blob:0x<>»
1834
1843
1835
- That way, you can safely concatenate it later on:
1836
1844
1837
- my Buf @buffs = Buf.new;
1838
- say [~] |@buffs, Buf.new(0x2, 0x22); # OUTPUT: «Buf:0x<02 22>»
1845
+ Please note that a similar issue may arise when reducing lists with
1846
+ other operators.
1839
1847
1840
1848
= head1 Maps
1841
1849
0 commit comments