Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Meditations

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

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User 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

RFC -- Evolving Perl: a Decision Theory Approach to the Challenges of Perl 7
3 direct replies — Read more / Contribute
by thechartist
on Jul 07, 2020 at 14:16

    The announcement of Perl 7 has created a lot of activity in the various techology communities I follow. It has also lead to a lot of discussion and debate among a number of subsets of the Perl community.

    Last week we had a discussion on "software quality" in the Perl Programmers Facebook group. "Quality" is a term that is not defined whenever it pops up. I pointed out that "quality" for a typical "real world" programming problem can be seen as a Multiple Criteria Decision Analysis, or a Multiple Objective Optimization Problem, that attempts to balance the following:

    1. Validate that inputs are appropriately transformed into the correct/desired outputs.
    2. Handle errors, exceptions, etc.
    3. Does so in a computationally efficient manner (ie. time and space efficiency). The algorithm doesn't need to be provably optimal, but it should be suitable for the *known* needs of the application at the time of writing.
    4. Delivered in a verifiable/testable form as quickly as possible.
    5. Comprehensible to other team members.
    6. Able to be relatively easy to change, if application specification changes.

    I'm sure there are other objectives I omitted. I think it should be obvious that:

    1. these dimensions need to be traded off against one another and
    2. these criteria aren't all equally weighted. Context determines what criteria are most important in a particular time.

    From a formal point of view, there are generally no unique/optimal solutions, only sets of satisfactory ones (Multiple Criteria Decision Analysis).

    Some of the themes of the p5p messages after the announcement included:

    1. What is the new contract with Perl users re: backward compatibility?
    2. What should be done in newer versions of Perl to attract new users?
    3. What should be done to ease the implementation of new features, and reduce the complexity of the Perl interpreter, toolchain, etc.
    4. What can be done to facilitate a better process for the community to make better decisions?

    The conclusions I've come to (as a former Perl hater, now Perl convert) is:

    1. Perl as a technology, scales from small one-liner throw away scripts, to massive code bases that span decades. There aren't many other languages that can boast about that.
    2. Perl, as a community, has learned a lot of lessons in producing reliable software. These lessons become part of Perl culture, and produce better developers.

    In terms of point 4 above (Perl community process), I'd like to suggest borrowing some methods from the operations research/decision analysis communities (Tools for Decision Analysis).

    The criteria I see the Perl community attempting to balance are:

    1. Perl interpreter complexity. Certain things need to be changed to improve computational efficiency, ease maintainence, and enhance the language.
    2. CPAN backward compatibility. Too much breakage with CPAN, and we have a new language with no code base.
    3. Increasing use of Perl in newer areas (ie. attracting new users, especially newer developers who can hack on the toolchain).
    4. Teaching the language, and good software development practice generally.

    An approach worth considering can be seen in the Ada community. Initially standardized in 1983, each revision (1995, 2005, 2012) has been accompanied by a Rationale document, that describes the changes and the reasons for them. Most of the changes have been addiitions or extensions to the language.

    Any rationale for future versions of Perl will be a bit more challenging, in that some practices will need to be revised. To explain and defend such changes, an explicit, pairwise comparison of what criteria are improved, and how they are traded off vs. other objectives, needs to be considered.

    I personally would like to see Perl more involved in so-called "data science." My use case for Perl is statistical natural language processing to assist in the meta-analysis or evidence synthesis of research in health care specifically, but in applied science more generally. I believe those tools could be helpful in exploring the CPAN code base to collect empirical data on what features of Perl are most used, and which could be dropped with minimal loss.

    If I'm thinking about this correctly, the problem the Perl community faces is one known in the Prolog and logic programming communities as inductive specification recovery. If I were to translate the informal problem facing the Perl community into a formal statement, I'd say we are attempting to discover (induct) the Perl grammar that simultaneously:

    1. Reduces CPAN Breakages
    2. Reduces Perl interpreter code complexity

    Damian Conway has shown how hard this path is via human effort Three Little Words.

    To calculate these things require some metrics. I think the CPAN breakage is reasonably easy to calculate. But the interpreter complexity metric is something that should be given some considerable thought.

    With an explicit decision model, I believe we can use statistical methods from reliability theory and machine learning to develop software that will ease the burden of transitioning Perl to a more sustainable future.

Amicable divorce
4 direct replies — Read more / Contribute
by ribasushi
on Jul 06, 2020 at 00:53

    ( this is a re-post of recent thoughts from the perl5-porters mailing list. Further interesting points articulated in an adjacent thread. )

    An incredibly unlikely combination of recent events have placed Perl (the language) at an exceedingly rare crossroads. Various "factions" have openly stated their worldviews, but war has not broken out just yet.

    While there is a ton of nuance, the two main "philosophies" at odds are roughly:

    • Software-as-a-solution (SAAS), where code is targeted at solving a specific problem, in a dynamic world. When the problem inevitably changes as the world around it continuously moves along, it is only fair and even prudent to continuously modify the existing solution to said problem.
    • Software-as-a-tool (SAAT), where code is targeted at *other* professionals, to combine it with an increasing array of other tools to then solve a specific problem. A hammer from 50 years ago looks strikingly identical to a hammer you can buy today, and it better look like a hammer after 2038, or else...

    The series of mega-threads all boil down to a profound misunderstanding within the p5p list itself of the magnitude of the clash-of-values between these sub-communities.

    I strongly believe, that if a more honest conversation takes places not over the "how" but the "what", a massive amount of effort will be saved on all sides.

    Specifically:

    • Instead of dancing around the issue of having nice things with cpan: let's admit the need for 2 CPANs: one to cater to folks excited by the prospect of perl 7 and one for people who will never write anything above 'use 5.0XX' within their code.
    • Begin a discussion acknowledging the amount of "better bash" tooling investment outside of the handful of companies named as stakeholders, and have an honest conversation what is the expectation for "system perl" and "system perlng" in the mid-to-long-term.

    Everything else discussed so far is dressing to obscure the substance: "Perl" and "perl" are *both* about ready to file for divorce. This is an incredibly rare chance for an Unionsupplösningen or a Velvet Divorce. Please, do not squander it.

    Cheers!

Breathing life into the (Emacs) cperl-mode
2 direct replies — Read more / Contribute
by haj
on Jul 02, 2020 at 11:29
    This also appeared on blogs.perl.org

    If you are an Emacs user, you might know or even use cperl-mode. I am using it, more or less since my first days with Perl. Back then, newsgroups were a thing, and Ilya Zakharevich recommended it occasionally. In older times cperl-mode was shipped with Perl, today it is part of Emacs.

    If you use cperl-mode, you might also have had a look at the code and noticed that it hasn't seen much love in the last decade or so. Perl, on the other hand, evolves. Version 5.32, for example, brings a new infix operator, and some future version might bring Cor. Wouldn't it be nice if cperl-mode understood these new keywords?

    I'm on my way to get familiar with emacs-lisp, ERT, and other stuff to see what I can do. Ideas, contributions, comments, bug requests and criticism is welcome - There's a GitHub repository to get started.

RFC: Destructuring Assignment (aka Unpacking aka Type Patterns) in pure Perl
3 direct replies — Read more / Contribute
by LanX
on Jul 02, 2020 at 09:41

    At yesterday online meeting of Germany PM we had a discussion about Destructuring Assignment aka unpacking aka Type Patterns which is available in languages like JS (ES6) and Haskell.

    I claimed it shouldn't be to difficult to do this in pure Perl, this is what I got so far.

    NB: This is a proof of concept !

    Neither syntactic sugar nor performance are at it's limits.

    (you know "release often ... yadda yadda" ;-)

    Grabbing of (almost greedy) lists @arr and %hsh not implemented yet.

    Comments welcome.

    use strict; use warnings; use Data::Dump qw/pp dd/; use Scalar::Util qw/reftype/; use autovivification; use Test::More; use constant DBG => 0; my @rules; sub parse_arr (\@$) { my ( $arr, $path ) = @_; for ( my $i=0; $i <= @$arr; $i++ ) { my $item = $arr->[$i]; parse( $item, "${path}[$i]"); } } sub parse_hsh (\%$) { my ( $hsh, $path ) = @_; while ( my ($key,$val) = each %$hsh ) { parse( $val, "${path}{$key}"); } } sub parse { my ( $item, $path ) = @_; $path //= ''; my $type = ref $item; return unless $type; if ( $type eq "GRAB") { push @rules, [ $item->{ref} , $path ]; } elsif ( $type eq "ARRAY" ) { parse_arr( @$item, $path ) } elsif ( $type eq "HASH" ) { parse_hsh( %$item, $path ) } else { warn "Unknown $type"; } } sub assign (++){ my ($pattern,$in) =@_; @rules = (); parse($pattern); warn pp @rules if DBG; no autovivification; for my $rule (@rules) { my ($ref,$path) = @$rule; my $code = "\$in->$path"; $$ref = eval($code); } } sub set (\[@$%]) { bless {ref => $_[0]}, "GRAB"; } my @pattern = ( 1,2,3, set my $y , [ 5,6, set my $z ] ); my $src = [ 1,2,3, 42 , [5,6, 666] ]; assign @pattern => $src; is_deeply ( [$z,$y], [666, 42], "AoA grabbing different levels" ); assign { u => [undef, set( my $u )], v => set my $v } => { u => [1,123] , v => "VVV"} ; is_deeply ( [$u,$v], [123,"VVV"], "HoA grabbing different levels" ); done_testing;

    C:/Perl_524/bin\perl.exe d:/exp/grab_assign.pl ok 1 - AoA grabbing different levels ok 2 - HoA grabbing different levels 1..2

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

Modernizing the Postmodern Language?
5 direct replies — Read more / Contribute
by WaywardCode
on Jun 29, 2020 at 12:44

    Fellow Monks,

    Today I re-read the 1999 talk: "Perl, the first postmodern computer language." I couldn't help but laugh to see that--as of this writing--the #1 advertised post on the right side-panel is the Perl 7 announcement, with the tag-line Perl 5 with modern defaults.

    Do we want our postmodern language modernized? It may not be the sound of one hand clapping, but still worthy of some meditation, I think. I recently noted that Perl 5.30 will run almost all of the Perl 1 test suite unmodified (the rare failures are on subroutines called with do whatever();). If I understand the Perl 7 plan correctly, Perl 7 will run approximately zero percent of the Perl 1 test suite due to mandating strict and dropping bareword filehandles. Does that matter? I guess not, but it feels like a loss to me.

    The virtues extolled in the talk were (1) incorporating what rules (2) leaving out what sucks and (3) letting the duct work show. To uphold those virtues, it seems to me that newer Perls should look around and incorporate things that both (1) rule and (2) aren't already in Perl. Perl should primarily accrete, and occasionally mutate. So, Monks, should it concern me that one of the two motivations given for Perl 7 is the ability to remove syntax? Should it concern me that SawyerX's Guac project (youtube) calls the regularized, easily-parsable subset of Perl "Standard Perl"? Despite the don't-worry-disclaimers, if the pumpking can call a language without autoquoting or heredocs Standard, that speaks volumes to me about where his head is at. Perhaps I am overreacting.

Java Recommendations for a Perl developer
6 direct replies — Read more / Contribute
by talexb
on Jun 16, 2020 at 22:12

    I'm currently doing Perl development, but there's a fair bit of Java code at work .. so I'm wondering if any monks can recommend a book, website or approach they found useful when getting up to speed.

    My background in Perl started in about '98, after about 15 years of developing C (with a few years of Pascal thrown in for good measure). Before that, I did development in a variety of assemblers (x86, 68000, 6809). I never did any C++, so any OO nomenclature I've picked up has been via Perl's take on OO.

    What I've seen of Java is that it's very hierarchical, and is also exception based -- Try::Tiny seems to neatly encapsulate the try / catch of Java.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

n-dim array generator
1 direct reply — Read more / Contribute
by jo37
on Jun 16, 2020 at 15:54

    Every now and then I need to create a n-dimensional array from some given formula, where n almost always is 1 or 2.
    I've been searching for a module providing such functionality without success. It would be a surprise if there really wasn't such a thing.

    But so I rolled my own and came to this:

    # arg_1 to arg_n specify size in dimension k, # last arg is a reference to a sub # - expecting n arguments x1 ... xn # - returning the desired value at $na->[x1]...[xn] sub narray { my $size = shift; my $val = pop; my $na; for my $i (0 .. $size - 1) { $na->[$i] = @_ ? narray(@_, sub {&$val($i, @_)}) : &$val($i); } $na; }
    which can be used in various ways and is not limited in dimension:
    $ar = narray(3, sub {$_[0]}); # [0, 1, 2] $mr = narray(3, 3, sub {$_[0] == $_[1] || 0}); # [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    just to get an idea.

    Does anybody know of a module providing something similar?
    Otherwise: Is this of use for someone else or would it even fit into something existing?

    UPDATE 1: This would be more perlish if the sub ref argument came first and the sub itself was prototyped:

    sub narray (&@); $ar = narray {$_[0]} 3;

    UPDATE 2: Incorporating LanX's suggestion of using map into UPDATE 1 results in:

    sub narray (&@); sub narray (&@) { my $val = shift; my $size = shift; [map {my $i = $_; @_ ? narray {&$val($i, @_)} @_ : &$val($i)} (0 . +. $size - 1)]; } my $na = narray {"<@_>"} 3, 2 # [['<0 0>', '<0 1>'], ['<1 0>', '<1 1>'], ['<2 0>', '<2 1>']]

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
foreach $1
1 direct reply — Read more / Contribute
by choroba
on Jun 05, 2020 at 17:49
    When answering a question on StackOverflow, I noticed an interesting anti-idiom (antidiom?) I haven't seen before (and haven't thought of trying):
    foreach $1 (@array)

    Interestingly, you can use it under strict and warnings and Perl doesn't protest. But $1 is aliased to the elements of the array and loses its magic behaviour:

    #!/usr/bin/perl use warnings; use strict; for $1 ('a' .. 'h') { print $1 if "A" =~ /(.)/; }

    Can you guess what the output is?

    So, if you ever get the idea of using special variables for something else than what they were designed to, stop.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
(Ab)using the Regex Engine
2 direct replies — Read more / Contribute
by jo37
on May 25, 2020 at 05:19

    The TASK #2 of perl-weekly-challenge-061 was to split a given string into certain subparts. There were two solutions that (ab)use Perl's regular expression engine to get all matches for the leading part of a regular expression. Though being one of the authors, I'm not so sure about this approach. How smart is the engine allowed to be? Is there a way to guarantee that it actually tries all possibilities?

    The section Embedded Code Execution Frequency in perlre says:

    How non-accepting pathways and match failures affect the number of times a pattern is executed is specifically unspecified and may vary depending on what optimizations can be applied to the pattern and is likely to change from version to version.
    This is a rather clear statement, that the proposed solutions may fail in future versions of Perl. But does this hold in any case? See examples in this program:

    #!/usr/bin/perl use strict; use warnings; my $match = qr[([ab]+)([ab]+)]; my $str = 'aba'; $str =~ /^ $match $ (?{ print "1: $1-$2\n" }) [c] /x; $str =~ /^ $match $ (?{ print "2: $1-$2\n" }) (?!) /x; $str =~ /^ $match $ (??{ print "3: $1-$2\n"; qr[(?!)] }) /x; __DATA__ 2: ab-a 2: a-ba 3: ab-a 3: a-ba

    Explanations to the numbered samples:

    1. There is a non-matched character class [c] at the end of the pattern. In my copy of the "Camel Book" (3rd Edition, 2000) it is stated that the engine is smart enough to optimize away the match attempt if there is a single character, but not if it is inside a character class. The engine has become smarter since then: the (?{CODE}) block is not executed.
    2. Currently, using a negative look-ahead assertion as a non-matcher outsmarts the engine into trying to match the string. I reckon that the matching attempt might be optimized away in future versions.
    3. With a small change, the resulting pattern remains the same but isn't known to the regex engine from the beginning, as the final part now is the returned value from a (??{CODE}) block. To decide if there is a match, the CODE has to be executed and thus cannot be optimized away. Would sniffing at the CODE and detecting that it always returns something non-matchable be "legal"? I feel kind of safe with this but I may be wrong.
    Would you agree with this statement, that seems to be in contrast to the quotation above?
    A (??{CODE}) block is guaranteed to be executed, if the failing or success of a pathway containing this block solely depends on the returned subexpression.
    Could we even have a zero-width assertion like (?!?{CODE}) that always fails but must not be optimized away in the sense of the previous proposition?

    I'd be glad to see your opinions.

    BTW: What matches and what is matched? Is a regex matching a string or is a string matching a regex? I don't know.

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Converting Hashes to Objects
9 direct replies — Read more / Contribute
by haukex
on May 17, 2020 at 09:13

    Inspiration whacked me in the head yesterday, and I realized that it was pretty easy to take an arbitrary hash reference and turn it into an object, so that instead of writing $hash->{key} I can just write $hash->key, saving two characters and giving me protection from typos. Enter Util::H2O:

    use Util::H2O; my $hash = h2o { foo => "bar", x => "y" }, qw/ more keys /; print $hash->foo, "\n"; # prints "bar" $hash->x("z"); # setter

    Deeply nested structures can be converted too...

    my $struct = { hello => { perl => { world => "yay" } } }; h2o -recurse, $struct; print $struct->hello->perl->world, "\n"; # prints "yay"

    The function blesses its hashref argument into a new package, and returns that hashref as well. The hashrefs otherwise remain the same as before, so you can still use $hash->{key} and so on if you like. The newly created package is cleaned up by default when the object is destroyed (configurable). These objects are of course a bit less performant than a regular hashref, but this wasn't intended for high-performance applications.

    Update: As of the freshly-released v0.06, the h2o function also locks the hash's keyset by default, to prevent typos when using the hash like a regular hashref. This can be disabled with the -lock=>0 option. /Update

    I quickly realized I could do more with this, like add methods to these objects:

    my $obj = h2o -meth, { one => 123, two => 456, sum => sub { my $self = shift; return $self->one + $self->two; } }; print $obj->sum, "\n"; # prints "579"

    And I could even make it easy to create classes; the -new option generates a constructor:

    h2o -class=>'Point', -new, -meth, { angle => sub { my $self = shift; atan2($self->y, $self->x) }, }, qw/ x y /; my $one = Point->new(x=>1, y=>2); my $two = Point->new(x=>3, y=>4); $two->y(5); printf "%.4f\n", $two->angle; # prints 1.0304

    Yes, I realize that might be taking it a little bit too far, but it was easy to implement - plus, I figured this could possibly be useful for whipping up mock objects in tests. And yes, I'm aware similar tools exist ;-)

Ways of quoting
4 direct replies — Read more / Contribute
by Aaronrp
on May 14, 2020 at 19:16

    I knew that you could use :: to make sure that a package name wasn't used as a subroutine, but I didn't really understand what it did.

    $ perl -MO=Deparse -e '$x = anything_could_go_here::' $x = 'anything_could_go_here'; -e syntax OK

    Just like single quotes?

    TIMTOWTDI I guess...

    So we have

    q{} '' => :: qw{} - (as in -bareword)

    And of course

    no strict; $x = bareword;

    not to mention

    "" and qq{} `` and qx{}

    Somebody will tell me that I missed some, I'm sure.

[OT] Am I just a bad programmer?
11 direct replies — Read more / Contribute
by maurocavendish
on May 08, 2020 at 07:33
    Hi, fellow monks!

    I've come to a point in my programming career when I seriously doubt that I have it in myself to go on. I worked years as a Perl programmer/system integrator. Few years ago, my company pulled me out of a project, and then it began. I was constantly moved on new projects, with new technologies stack, ranging from PHP, Python, AngularJS, Struts, Spring Boot, Vue, SQL Server, Node, React. You name it. As I understand, I am now under the umbrella of the Java Competence Center, so they expect me to deliver on that.

    I never received any guidance, training, or support. Every project since then I was, sometimes literally, alone. Of course, my boss wants me to deliver fast and clean. At the moment, I am working on a huge Java project, again on my own. I'm in charge of analysis, development, sometimes testing. Also, no one gave me a proper introduction to the app we are developing, that is heavy on financial business logic. All the while, despite having worked in the field for more than 10 years, my current job title is Junior Software Developer, with no hope of advancing given the current situation.

    I feel like I've reached a wall. I cannot deliver. I have constant migraines. All in all, I fear I'll lose my job. Is this just a sign that I'm not cut out for the job, or that I'm perhaps too old to keep up (I'm 42)? I still study in my spare time what fascinates me, but I'm beginning to hate programming, and I'm not putting in the same amount of work into my education as I did when I started. I'd need some real side projects under my belt to brush up my resume, but I do not have the spare mental capacity to push even outside the workplace.

    Unfortunately, it seems that here in Italy all the coding jobs are like so, therefore I'm questioning my worth in the market as a programmer. Soon I think I'll try to switch company, but I'm not convinced anything would really change. Is a valuable professional programmer required to just go along with everything the company throws at him, or is it more sensible to craft a specific role in the spare time and go for it elsewhere?

    I understand this post is highly OT, but I could seriously use some help for maturing a better understanding.

    Regards.

    Training is everything
Why a regex *really* isn't good enough for HTML and XML, even for "simple" tasks
8 direct replies — Read more / Contribute
by haukex
on May 05, 2020 at 07:41

    TL;DR: Working code below!

    Say you "just" want to extract some links. Are you sure the HTML's formatting will never change (whitespace, order of attributes, its structure, and so on)? Well, here's some perfectly valid HTML - good luck!

    Solutions that work on all of the above:


Add your Meditation
Title:
Meditation:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":


  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • 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 musing on the Monastery: (6)
    As of 2020-07-13 21:52 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found

      Notices?