Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Perl6::Form Issues with Zero-Padding and Declarative Width

by AnaximanderThales (Novice)
on Nov 17, 2014 at 17:03 UTC ( #1107442=perlquestion: print w/replies, xml ) Need Help??

AnaximanderThales has asked for the wisdom of the Perl Monks concerning the following question:

Perhaps I'm breaking Perl6::Form through incorrect usage. I'm still learning programming in general, and Perl specifically. At this point I believe I'm just misinterpretting that that what I'm trying to do is actually appropriate to do with Perl6::Form.

First, I chose to use Perl6::Form because I have the ability to set the columns that I'm attempting to fit the information into. I could find no way to do that with 'format.' Additionally, one PerlMonks item I've read, Form is a much easier implementation that builds off of format.

Enough schmoozing -- on to the issues.

I have this code:

# Test Perl6::Form -- submitting code for Perl Monks # zero-padded fields appears to be broken # Declarative width fields appears to calculate the field length # incorrectly use strict; use warnings; use diagnostics; use Perl6::Form; my $columns = 44; my $fID = "TEST"; my $tID = "003 "; my $space = " "; my $fPer = "Test"; my $tPer = "100.0"; my $fVal = "Int for Zero Pad"; my $tVal = "3"; my $fFlo = "Float for Zero Pad"; my $tFlo = 3.2; # Produces error for invalid field length print "Length = " . length($tID) . "\n"; print form { page => { width => ($columns + 1), } }, "{<<{15}<<}|{>(5)>}|{><}|{<<{15}<<}|{>(5)>}%|", $fID, $tID, $space, $fPer, $tPer; # When above is commented out print form is commented out # Produces Use of uninitialized value $whole in pattern match (m//) print form { page => { width => ($columns + 1), } }, "{<<{20}<<}{0>>>>>}", $fVal, $tVal, "{<<{20}<<}{0>>>.>>0}", $fFlo, $tFlo;

I'm not actually interested in using the first 'print form' section (invalid field length), but in trying to make it work correctly, I tried it out. When I have that uncommented and manually format the text to what I want, I receive this error:

Length = 5 Uncaught exception from user code: Inconsistent width for field 2. Specified as '{>(5)>}' but actual width is 7 in call to &form at test_perl6Form.pl line 33. Perl6::Form::fatal("Inconsistent width for field 2.\x{a}", "Specif +ied as '{>(5)>}' but actual width is 7") called at /usr/local/share/p +erl/5.20.1/Perl6/Form.pm line 663 Perl6::Form::segment("{<<{15}<<}|{>(5)>}|{><}|{<<{15}<<}|{>(5)>}%| +\x{a}", ARRAY(0x1e676b8), HASH(0x1e5d400), 0, HASH(0x1e5d448)) called + at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 1097 Perl6::Form::form(undef, undef, "TEST", "003 ", " ", "Test", 100. +0) called at test_perl6Form.pl line 33

In running the code, the length is actually 5. Not sure why it registers +2, but it seems consistent to add 2 extra positions in the length.

The MAIN issue occurs off the second 'print form.' Form breaks when attempting to zero-pad the field. After commenting out the manual padding sections (# Due to bug ... # Begin formatting based on columns), when I run the script I get:

Use of uninitialized value $whole in pattern match (m//) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 340 (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl will try to tell y +ou the name of the variable (if any) that was undefined. In some cas +es it cannot do this, so it also tells you what operation you used th +e undefined value in. Note, however, that perl optimizes your progr +am and the operation displayed in the warning may not necessarily app +ear literally in your program. For example, "that $foo" is usually optimized into "that " . $foo, and the warning will refer to the concatenation (.) operator, even though there is no . in your program. Use of uninitialized value $places in pattern match (m//) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 341 (#1) Use of uninitialized value $whole in pattern match (m//) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 342 (#1) Use of uninitialized value $whole in repeat (x) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 359 (#1) Use of uninitialized value $point in concatenation (.) or string at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 359 (#1) Use of uninitialized value $places in repeat (x) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 359 (#1) Use of uninitialized value $whole in repeat (x) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 360 (#1) Use of uninitialized value $point in concatenation (.) or string at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 360 (#1) Use of uninitialized value $places in repeat (x) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 360 (#1) Use of uninitialized value $point in string ne at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 369 (#1) Use of uninitialized value $whole in numeric gt (>) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 399 (#1) Use of uninitialized value $w in concatenation (.) or string at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 403 (#1) Use of uninitialized value $p in concatenation (.) or string at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 403 (#1) Use of uninitialized value $point in concatenation (.) or string at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 412 (#1) Use of uninitialized value $whole in subtraction (-) at /usr/local/share/perl/5.20.1/Perl6/Form.pm line 413 (#1)
Int for Zero Pad Float for Zero Pad .
So -- the question is: am I breaking Perl6::Form by using it incorrectly? Should I be filing a bug report? Or am I just doing it wrong?

Replies are listed 'Best First'.
Re: Perl6::Form Issues with Zero-Padding and Declarative Width (integer)
by Anonymous Monk on Nov 18, 2014 at 04:01 UTC

    Yes, i think there is some kind of bug in there, either a documentation bug, or implementation bug, or both

    perl6form doesn't have an INTeger field, so  {0>>>>>} doesn't mean zero pad (that is only documented for decimal numbers ie floats)

    Also, zero padding numeric fields only shows using {]].[[} not {>>.<<} so that could be a doc bug or implementation bug (not implemented, or error not detected)

    So to fill that integer field with zeros you have to use lfill right before the value ... this works

    #!/usr/bin/perl -- use strict; use warnings; use diagnostics; use Perl6::Form qw/ form /; print form { page => { width => ( 44 + 1), } }, "{<<{20}<<}|{>>>>>}", "Int for Zero Pad", {lfill => '0',} , 3 , "{<<{20}<<}|{]]].[[}", "Float for Zero Pad", 3.2, "{<<{20}<<}|{]]].[[0}", "Float for Zero Pad", 3.2, "{<<{20}<<}|{0]]].[[0}", "Float for Zero Pad", 3.2, ;;;;; __END__ Int for Zero Pad |0000003 Float for Zero Pad | 3.2 Float for Zero Pad | 3.2000 Float for Zero Pad |00003.2000

    So maybe the implementation is incomplete, doesn't do the padding, or doesn't warn about invalid field pattern .... good job finding this AnaximanderThales

      Yes, having received an email back from Damian (creator/maintainer of Perl6::Form), it was completely usage issues.

      For the zero-padding, you have everything mentioned. I was using it incorrectly based on your response. My issue with the float zero-padding was just the symantics. I had {0>>>.>>0} and the correcte usage is {0>>>.<<0} notice the change from > to < at the decimal point

      Additionally, as AM said, there is no INT padding, so the lfill (or rfill) is the correct method.

      I'm still a little confused by Damian's response on the Declarative Width ({<(5)<}), but I'm working on figuring it out.

      ME:
      The length give by perl shows that the field is actually 5 positions.
      Damian:
      No. The length of the *data* for the field is 5. :-) The *field* is the specification "{>(5)>}", which is definitely 7 characters in width (and hence invalid, since the "(5)" specifies that the surrounding field must be 5 characters wide. In other words, declarative field widths are not about validating the data to be interpolated; they are about checking that the field specification itself is consistent. In practice, declarative field widths are mostly only used for formats that have been autogenerated, as a way of checking that the field you somehow constructed is the correct width. They are not in any way about verifying the data to be formatted into a field. In fact, form() has no features for validating the data it formats. It just does its best to accommodate whatever data you through at it.
      ME:
      I'm curious as to why perl would say $tID is length 5 but form would say $tID is length 7.
      Damian:
      That's the misunderstanding in a nutshell. form() isn't saying the contents of $tID is of length 7; it's saying that the specifier for the "{>(5)>}" field into which $tID is being formatted is of length 7.

      I'm mulling Damian's definition about how the declarative width field operates. It's kind of making my head swim at the moment. I'll bang away on it until that little 1/16" turn makes it slip into place in my mind.

      I appreciate all the answers, and Damian's response. Thank you. @

        Hey there,

        Glad you got it mostly sorted out and working. I'm sorry that my quick attempt to help was off the mark. But it did relate to your outstanding question about declarative field widths. Maybe this will help:

        Declarative field widths add no formatting information. The field you were talking to Damian about was this:

        {>>>>>}

        Clearly a field of 7 characters. There is no other information in order for this field to be used at this point. If in addition, you want an automatically validated "checksum" to ensure that the field is actually the width you intended, you can add it as a length inside parentheses:

        {>(7)>}

        The field is still 7 characters long, just as before. The form code will rip the "(7)" out, validate that the 7 matches the actual field length, and then logically replace it with ">>>" to restore the real format.

        None of this is very useful for a field of 7 characters, it can be eyeballed as correct pretty easily. But for a field of say 50+ characters, it's nice to have a double check.

        Yeah, his docs are always novels :) see https://metacpan.org/pod/Perl6::Form#Declarative-field-widths, its what hes talking about ... this example might be clearer

        field of length ten  {<<<<<<<<<}

        field of length ten with CHECKSUM  {<<(10)<<<} basically the number has to match the literal length of the field including every single character like {}, basically length of the string , if it isn't, it errors (programmer made typo fix it programmer fix it)

        field of length ten with TELLSUM  {<{10}<}, the length of this string is 8 characters, but the { curly braces } mean don't count characters for length, just use the number, so the field width is 10

        field of length ten with TELLSUM  {<<<<<<<{10}<<<<<<<}, the length of this string is 20 characters, but the { curly braces } mean don't count characters for length, just use the number, so the field width is 10

Re: Perl6::Form Issues with Zero-Padding and Declarative Width
by Anonymous Monk on Nov 18, 2014 at 01:00 UTC

    So -- the question is: am I breaking Perl6::Form by using it incorrectly? Should I be filing a bug report? Or am I just doing it wrong?

    Too much data presented to answer any questions

    You need to boil down your question to one function call with one set of data

    my $data = Dumper output here print form .... $data...

    This is the beginning :)

      Per Response, editted initial post to the basics.

        Change:

        "{<<{15}<<}|{>(5)>}|{><}|{<<{15}<<}|{>(5)>}%|"
        to:
        "{<{15}<}|{>{5}>}|{><}|{<{15}<}|{>{5}>}%|"
        Update: Which only removes the error message... padding issue still remains as AM says.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1107442]
Approved by Jim
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (1)
As of 2021-05-09 04:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (100 votes). Check out past polls.

    Notices?