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 )