Arithmetic-PaperAndPencil
view release on metacpan or search on metacpan
doc/documentation.en.md view on Meta::CPAN
```
# Perl
for my $line (@sheet) {
unshift @$line, (Arithmetic::PaperAndPencil::Char->space_char) x $delta_c;
}
```
It did not work. Test programme `01-action.t` (Raku-to-Perl
translation of `06-html.rakutest`) would write `133` where I was
expecting `123`. After some debugging, I understood that one each
line, the `unshift` statement would insert the same `A::P&P::Char`
instance twice. On the other hand, the problem was not appearing in
Raku. Either formula `space-char() xx $delta-c` calls twice function
`space-char` and gets two different instances of `A::P&P::Char`, or
the `prepend` statement deep-copies its argument into the list. Either
way, I had to fix the Perl version and write:
```
# Perl
for my $line (@sheet) {
for (1 .. $delta_c) {
unshift @$line, Arithmetic::PaperAndPencil::Char->space_char;
}
}
```
### Second problem with `A::P&P::Char`
The `01-action.t` test programme generates two HTML strings. When
writing class `A::P&P::Char` and method `html`, I activated only the
first HTML string generation until it was completely implemented and
debugged. Then, when I activated the second HTML string generation, it
was no longer working. With the help of a few debugging trace
messages, I pinpointed an error in at least `check_l_min` and
`l2p_lin` inner functions. Maybe the same error was occurring in the
other inner functions: `check_c_min`, `l2p_col` and `filling_spaces`,
I did not check. Here is the explanation with only `l2p_lin` for
brievety's sake. Here is the function:
```
# Perl
sub l2p_lin($logl) {
my $result = $logl - $l_min;
return $result;
}
```
This function uses a formal call parameter `$logl` and a global
variable `$l_min` (actually a lexical variable with a scope extending
beyond function `l2p_lin` to the outer method). During the first HTML
string generation, variable `$l_min` would have the successive values
0, -1, -3 and -4 (skipping -2 because we insert two columns in one
go). Yet, during the second HTML string generation, `$l_min` would
have a strange behaviour. When printed from outside the `l2p_lin`
function, I would have values 0, -1, -3 and -4, but when printed from
within the `l2p_lin` function it would always give -4.
Here is the hypothetical explanation. During the first generation,
function `l2p_lin` would use the proper value for `$l_min`, that is,
0, then -1, then -3 and lastly -4. When method `html` ends, function
`l2p_lin` is still alive thanks to the closure mechanism. And thanks
to the same closure mechanism, variable `$l_min` still exists with
value -4 because it is used by `l2p_lin`. Then, method `html` is
called a second time to check CSS usage. This defines a new instance
of variable `$l_min`, initialised to 0. On the other hand, when
reading the definition
```
# Perl
sub l2p_lin($logl) {
my $result = $logl - $l_min;
return $result;
}
```
the function is not redefined, the old definition is still in effect.
So the next calls to `l2p_lin` call the closure function, with the
closure variable `$l_min`, still equal to -4. The fix was very simple,
adding keyword `my`:
```
# Perl
my sub l2p_lin($logl) {
my $result = $logl - $l_min;
return $result;
}
```
I have written above that I did not bother to check whether the same
problem occurred with `check_c_min`, `l2p_col` and `filling_spaces`.
Actually, I involuntarily checked this in another function. The `html`
method contains another inner function, `draw_h` and at first, I
forgot to add a `my` to this function. And running `01-action.t`
resulted in a failure, because some underlining was not done when
needed. After adding `my`, the test was successful.
### Problems with `A::P&P::Number`
In a few places within this class, I need to convert a single-digit
`A::P&P::Number` instance into a native Perl or Raku integer. In Raku,
I declare a 36-element array:
```
# Raku
@digits = ( '0' .. '9', 'A' .. 'Z');
```
and I search the processed digit `$.unit.value` within this array to
obtain its index with:
```
# Raku
my Int $units = @digits.first: * eq $.unit.value, :k;
```
There is a Perl equivalent, provided module
[`List::MoreUtils`](https://metacpan.org/pod/List::MoreUtils)
is installed. Just use function
[`first_index`](https://metacpan.org/pod/List::MoreUtils#firstidx-BLOCK-LIST)
aka `firstidx`. I wrote:
( run in 0.644 second using v1.01-cache-2.11-cpan-df04353d9ac )