Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

The Monastery Gates

( #131=superdoc: print w/replies, xml ) Need Help??

Donations gladly accepted

If you're new here please read PerlMonks FAQ
and Create a new user.

Quests
poll ideas quest 2020
Starts at: Jan 01, 2020 at 00:00
Ends at: Dec 31, 2020 at 23:59
Current Status: Active
9 replies by pollsters
    First, read How do I create a Poll?. Then suggest your poll here. Complete ideas are more likely to be used.

    Note that links may be used in choices but not in the title.

Perl News
Announcing Perl 7
on Jun 24, 2020 at 15:14
18 replies by marto
Reminder: The Perl and Raku Conference in the Cloud - this week!
on Jun 22, 2020 at 04:36
2 replies by haukex
Supplications
Contents of @_ using subroutine signatures with default values
3 direct replies — Read more / Contribute
by davido
on Jul 13, 2020 at 18:22

    perlsub states the following:

    When using a signature, the arguments are still available in the special array variable @_ , in addition to the lexical variables of the signature.

    We can confirm this:

    sub baz ($this, $that) { warn '@_ contains ', scalar(@_), " elements.\n"; } baz('hello', 'world') # @_ contains 2 elements.

    But what happens when one of the parameters is optional?

    sub foo ($this, $that = 'world') { warn '@_ contains ', scalar(@_), " elements.\n"; } foo('hello'); # @_ contains 1 elements.

    Here's an example with tests:

    #!/usr/bin/env perl use strict; use warnings; use feature qw(signatures); no warnings qw(experimental::signatures); use Test::More tests => 8; sub baz($this, $that) { ok defined($this), "\$this is defined and contains $this"; ok defined($that), "\$that is defined and contains $that"; is scalar(@_), 2, '@_ has two elements.'; is_deeply \@_, [$this, $that] or diag 'Parameters: ', explain { this => $this, that => $that, at_underscore => \@_ }; } sub foo ($this, $that='bar') { ok defined($this), "\$this is defined and contains $this"; is $that, 'bar', '\$that contains "bar"'; is scalar(@_), 2, '@_ has two elements.'; is_deeply \@_, [$this, $that] or diag 'Parameters: ', explain { this => $this, that => $that, at_underscore => \@_ }; } note "\n\nTesting baz()"; baz('hello', 'world'); note "\n\nTesting foo()"; foo("a");

    The output is...

    1..8 # # # Testing baz() ok 1 - $this is defined and contains hello ok 2 - $that is defined and contains world ok 3 - @_ has two elements. ok 4 # # # Testing foo() ok 5 - $this is defined and contains a ok 6 - \$that contains "bar" not ok 7 - @_ has two elements. # Failed test '@_ has two elements.' # at mytest2.pl line 24. # got: '1' # expected: '2' not ok 8 # Failed test at mytest2.pl line 25. # Structures begin differing at: # $got->[1] = Does not exist # $expected->[1] = 'bar' # Parameters: { # 'at_underscore' => [ # 'a' # ], # 'that' => 'bar', # 'this' => 'a' # } # Looks like you failed 2 tests of 8. shell returned 2

    This has probably been discussed a lot somewhere.

    The question: Is the reason that scalar(@_) does not contain aliases to optional values so that we can determine how many parameters were actually passed, and if so, should it be documented?


    Dave

Logarithmic Scale
2 direct replies — Read more / Contribute
by aplonis
on Jul 13, 2020 at 06:22

    Trying to generate an SVG for an azimuthal antenna plot from a single column of values in decibels, range -40 up to a fixed maximum of 10. I've got it working, sort of. But the concentric rings for -40, -30 ... +10 are all of evenly spaced diameters. So it doesn't look right compared to the usual way. Normally the outer donut for 0 to +10 is bigger than the next one down for -10 to 0. And so on, each ring getting thinner and thinner as it proceeds down to the innermost circle with a center point of -40 dB.

    So this is likely more a math question, except that I'm trying to work it in Perl. Obviously, Perl/Tk does it somehow, since a log scale exists. Has anyone a link to such an example?

    Here is a link to what I'm working on. Folder on KY8D.net

    foo.n2p.txt is the data. Drop the .txt after download.
    foo.svg is the SVG graphic created by Perl.
    Nec2Go_Plot.png is the plot I'm trying to prettify.
    N2P_to_SVG.txt is the Perl script.

    What it's about: There's an older antenna analysis program called Nec2Go. I'm wanting to make its plots suitable for inclusion in magazine articles, etc. So its 1-pixel lines on plots with grey backgrounds just won't do. Otherwise, though, it's better than certain newer ones.

Ternary Quizical behaviour?
8 direct replies — Read more / Contribute
by bliako
on Jul 10, 2020 at 07:35

    I have a possibly bad habit to compact boring parts of my code like this:

    if( exists($hash->{akey}) && defined($m=$hash->{akey}) && ($m==1) ){ $ +y = $m; ... } # don't trust $m here

    But in this case it has unexpected results. This is the 1st part where a hash is constructed based on whether a key in another hash exists:

    use strict; use warnings; use Data::Dumper; my %tests = ( 'a' => 10, 'b' => 20, ); my $m; # this seems to assign $m once and never bother to check again my %hash = ( 'b' => exists($tests{'b'}) && defined($m=$tests{'b'}) ? $m : 0, 'a' => exists($tests{'b'}) && defined($m=$tests{'a'}) ? $m : 0, ); print Dumper(\%hash); # this works as expected $m = 10; my %hash2 = ( '1' => $m++, '2' => $m++, '3' => $m++ ); print Dumper(\%hash2);
    $VAR1 = { 'a' => 10, 'b' => 10 }; $VAR1 = { '1' => 10, '2' => 11, '3' => 12 };

    Does anyone have an explanation? And is my habit bad?

Perl::Critic says don't modify $_ in list functions and other things
9 direct replies — Read more / Contribute
by Lady_Aleena
on Jul 08, 2020 at 21:29

    Hello all. I have been playing around with Per::Critic on the command line and found to my dismay that some of my modules do not pass gentle. I realize that I can ignore the recommendations of Perl critic, but I would love for my modules to pass "gentle" before I begin ignoring things.

    The most common issue is that I modify $_ in list functions. The following is a convenient and short one liner to put the lines of files into a list. I thought doing it this way was nice and slim.

    my @list = map { chomp($_); $_ } <$fh>; my @uc_list = map { chomp $_; [uc $_] } <$lc_fh>; # used only onc +e my @split_list = map { chomp $_; [ split(/\|/, $_) ] } <$piped_fh>; +# used only once

    In one subroutine, I have this three times.

    Also, my idify subroutine is just modifying $_.

    And my Fancy::Map modifies $_ too.

    If this is something ignored usually, I will ignore it, but I would like to know how to make it better. Should I just assign $_ to a variable and then use the variable?

    Another thing that I am confused by is why the expression form of eval is discouraged?

    The rest of the gentle issues are me being lazy with conditionals. While writing I was thinking my $var = "foo" if 'some condition', but Perl critic does not like it, but it is fixed easily.

    NOTE: Please see my update. Most are fixed, but the eval problem remains.

    My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.8.8 on web host.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
Why eval $version?
3 direct replies — Read more / Contribute
by Aldebaran
on Jul 08, 2020 at 18:22

    I'm still processing what I experienced at TPC. I've had time to catch up on some of the youtube videos from the ones I missed. Sometime in all the zooming, I thought I heard one of the presenters say

    that's why we eval version

    I thought it was Sawyer X, who says a lot of things parenthetically, but I went over his talk for a third time and didn't hear it again. I didn't understand what he meant, so I could well have misheard it or just dreamed up the recollection wholesale.

    A couple days later, I'm going through the guts of a test script for local::lib and I see this, beginning line 16 of xt/bootstrap.t

    sub check_version { my ($perl, $module) = @_; my @inc = `$perl -le "print for \@INC"`; chomp @inc; (my $file = "$module.pm") =~ s{::}{/}g; ($file) = grep -e, map { "$_/$file" } @inc; return undef unless $file; my $version = MM->parse_version($file); eval $version; }

    Q1) What purpose does this line serve?

     eval $version;

    Q2) Is this a "string eval?"

    Q3) Do dangers lurk in its use, cf. Uri Guttman's 2019 TPC talk on 'eval'?

    Q4) Does anyone else remember the "that's why we eval version" comment, or is it just me?

    Thanks for your comment,

Detect boundaries within .png's - and cropping
6 direct replies — Read more / Contribute
by Stickybit
on Jul 08, 2020 at 02:30

    Hi everyone

    Got at specific problem, that I need some hints on. :-)

    I got a bunch of fixed size .png images with logos. Those logos are centered on the images, and empty space on the left/right of the logo, is transparent background. I need to crop those images on the fly, so that empty space on the left/right of the logo is removed.

    Any hints on how to solve that one? :-)

Meditations
Expression form of map or grep
7 direct replies — Read more / Contribute
by Lady_Aleena
on Jul 10, 2020 at 15:47

    As you might know, I have been using Perl::Critic on my code over the last several days. After I finished checking my code on the gentle setting, I kicked it up a notch and used stern. Well, Perl::Critic set on stern gave me screens full of problems, and the biggest one is I use the expression form of map and grep. I looked around the web to find out why.

    Here is my opinion that could be very wrong.

    All of the examples I found of the expression form of map and grep would lead to inevitable problems, and I can see why the writers of those examples would jump on using the block form for both. However, the one thing all of the examples had in common is the disuse of parentheses. I feel that if the expression form of a map or grep is used with parentheses, it is contained within them.

    The map below would lead to problems, since there is nothing containing the expression or on which list(s) the map is being applied.

    my @colors = qw(red yellow green cyan blue magenta); my @grey_scale = qw(white grey black); my @list = map "$_ beads", @colors, @grey_scale;

    However, I do not think this needs a block form to contain the map and list if parentheses are used.

    my @list = map( "$_ beads", @colors ), @grey_scale;

    Now the map is contained within parentheses, and @grey_scale does not get beads mapped to it. However, if one must use the block form, parentheses would still be needed to contain the mapped items.

    my @list = ( map { "$_ beads" } @colors ), @grey_scale;

    I think the expression form with parentheses is easier on the eyes, but it is just my opinion. I can understand using the block form if the map were more complex, however, I think I would write a separate subroutine instead of loading the block with more than two or three modifications and use the expression form.

    Converting from expression to block form is also problematic as it is not always as simple as the above would suggest, especially with grep. I have also found the expression form of grep to be easier to use, in one case (I can not remember the specifics) I could not get the block form of grep to work.

    If I use sort with map and/or grep on the same list, I will wrestle the block forms until I get the results I want, because in that case, it is easier on my eyes than trying to mix expression forms with the block of sort.

    I know I can ignore Perl::Critic's results on this and other issues, however, I do want code that is more acceptable by the community. So, I am trying to decide if I want to start wrestling with Perl on this or not. (I ran Perl::Critic on all of my modules, and it found 330 lines where I used the expression forms of map and grep, so this is fairly big to me.)

    I hope I am not too wrong about this.

    My OS is Debian 10 (Buster); my perl versions are 5.28.1 local and 5.16.3 or 5.30.0 on web host depending on the shebang.

    No matter how hysterical I get, my problems are not time sensitive. So, relax, have a cookie, and a very nice day!
    Lady Aleena
RFC: Version::Easy
3 direct replies — Read more / Contribute
by LanX
on Jul 10, 2020 at 13:28
    Following the discussion in Why eval $version? I'd like to propose the following approach.

    Usage

    use Version::Easy; $VERSION = 'v1.2.3'; # v-str # or... $VERSION = '1.002003'; # float $VERSION = 'v1.2.3_4'; # v-str + alpha $VERSION = '1.002003_4'; # float + alpha

    please note that:

    • Version::Easy adds magic to $VERSION
    • it's also declaring $VERSION in the caller's package, so no our needed
    • all formats like floats or v-strings with optional "_alpha" allowed
    • no boilerplate eval or tr/// needed
    • version is used internally, which is the same mechanism applied by use
    • syntax check at runtime
    • toolchain modules with static parser find "$VERSION" as usual
    Implementation:
    • $VERSION is a tied scalar,
    • in STORE the version number is checked for correct syntax
    • in FETCH a version object is returned
    • the version object is overloading all necessary operators
    • for older versions of Perl the implementation could adapt dynamically to sane defaults
    • if the performance impact is too heavy for normal runs, it's possible to limit the costly parts only to run inside the test suite.

    Doesn't this solve most (or all) problems???

    Please comment! Where does this fail? :)

    use strict; use warnings; # -------------------------------------------------- package Version::Easy; use Data::Dump qw/pp dd/; use version; sub import { my $pkg = (caller)[0]; my $version; tie $version, 'Version::Easy::Tie'; no strict 'refs'; *{${pkg}."::VERSION"} = \$version; } # -------------------------------------------------- package Version::Easy::Tie; require Tie::Scalar; our @ISA = qw(Tie::StdScalar); use version qw/is_lax/; sub STORE { my ($self,$value)= @_; warn "IN:\t\t",$value; if ( is_lax($value) ) { $$self = version->parse($value); } else { warn "corrupt VERSION format $value"; } } # BUG? perldoc Tie::Scalar says no TIESCALAR needed sub TIESCALAR { my $class = shift; my $version; return bless \$version, $class; } 1; # -------------------------------------------------- # --- fake already required for 'use' demo BEGIN { $INC{'Version/Easy.pm'} = 1; } # -------------------------------------------------- # # DEMO # # package TST; use Version::Easy; # --------- test v-str $VERSION = 'v1.2.3'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v1 = $VERSION; # --------- test float $VERSION = '1.002003'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v2 = $VERSION; warn "Are both Version equal?:", $v1 == $v2; warn "v-str bigger?:", $v1 > 'v1.2.2'; warn "v-str smaller?:", $v1 < 'v1.2.4'; warn "v-str not smaller?:", $v1 < 'v1.2.2'; # # --------------------------------------------------

    -*- mode: compilation; default-directory: "d:/exp/" -*- Compilation started at Fri Jul 10 19:13:58 C:/Perl_524/bin\perl.exe d:/exp/Version_Easy.pl IN: v1.2.3 at d:/exp/Version_Easy.pl line 29. Str: v1.2.3 at d:/exp/Version_Easy.pl line 69. Float: 1.002003 at d:/exp/Version_Easy.pl line 70. V-str: v1.2.3 at d:/exp/Version_Easy.pl line 71. IN: 1.002003 at d:/exp/Version_Easy.pl line 29. Str: 1.002003 at d:/exp/Version_Easy.pl line 78. Float: 1.002003 at d:/exp/Version_Easy.pl line 79. V-str: v1.2.3 at d:/exp/Version_Easy.pl line 80. Are both Version equal?:1 at d:/exp/Version_Easy.pl line 84. v-str bigger?:1 at d:/exp/Version_Easy.pl line 86. v-str smaller?:1 at d:/exp/Version_Easy.pl line 87. v-str not smaller?: at d:/exp/Version_Easy.pl line 88. Compilation finished at Fri Jul 10 19:13:58

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

PerlMonks Discussions
Offering Plate needs some brasso
2 direct replies — Read more / Contribute
by perlfan
on Jul 12, 2020 at 10:17
    It mentions that TPF "... carries the legal responsibility for Perl 5 and Perl 6..", which is clearly out of date. Also the links are non-SSL. Not exactly something you want to note when going to donate, e.g. - it does redirect to https://donate.perlfoundation.org/, but not before you've already made a request to http.

    My last note is a thought, would it be to remove the unnecessary clicks in our "Donate" link above, and just link from here to https://donate.perlfoundation.org/donate.html. Idk if Dan is on here, but that page should probably get a face lift so that it has some of the info that's on https://donate.perlfoundation.org and may be more suitable for direct linking.

    minor update, s/what's/the info that's/.

Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (2)
As of 2020-07-15 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?