in reply to Make $^V and "my" implicit

This seems connected to one of my pet peeves: why do people put use 5.010 (or higher) in code that is destined for CPAN when the only feature being used is something like say or //=? Why break backwards compatibility for what are, in my opinion, trivial reasons? Is it unreasonable for me to think that gunzip would do that?

That is not to say that when one is writing code for a closed environment, i.e. $work, where everything is fully controlled then by all means write for the latest and greatest that you have confidence in and take full advantage of new features! But keep in mind that there is a great difference between a private environment such as $work, and a public one such as CPAN. Please don't assume that others who want to use an otherwise great CPAN module have the environment that will allow them to use anything higher than 5.8 unless there are compelling reasons to disregard those users.

To be fair, performance could differ between using older code and a newer feature, as the following demonstrates (OS X 10.9, perl v5.16.2). But I honestly think that it would be rare indeed for something like this to even begin to affect the run-time of a real application.

#!/usr/bin/perl use v5.16; use warnings; use Benchmark qw/cmpthese/; my $foo = { bar => 'baz', baz => undef, }; my $foo1 = {}; sub _ifdefined { for ( keys(%{$foo}) ) { $foo1->{$_} = 'default' unless defined($foo->{$_}); } } sub _definedor { for ( keys(%{$foo}) ) { $foo1->{$_} //= 'default'; } } cmpthese( -5, { _ifdefined => sub { _ifdefined() }, _definedor => sub { _definedor() }, } ); exit; __END__ Output: Rate _ifdefined _definedor _ifdefined 1081314/s -- -12% _definedor 1228949/s 14% --

NOTE: if $foo1 is initialized inside the sub-routines then the output changes to this:

Rate _ifdefined _definedor _ifdefined 511025/s -- -1% _definedor 514053/s 1% --
It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

Replies are listed 'Best First'.
Re^2: Make $^V and "my" implicit
by BrowserUk (Patriarch) on Feb 04, 2014 at 00:49 UTC

    Bad benchmarks do not a good case make:

    #! perl -slw use strict; use Benchmark qw[ cmpthese ]; our $fred = 'fred'; our $bill = undef; cmpthese -1, { definedor => q[ for( 1 .. 1e3 ) { $fred //= 'fred'; $bill //= 'bill';; } ], unlessdefined => q[ for( 1 .. 1e3 ) { $fred = 'fred' unless defined $fred; $bill = 'bill' unless defined $bill; } ], ternary => q[ for( 1 .. 1e3 ) { $fred = defined $fred ? $fred : 'fred'; $bill = defined $bill ? $bill : 'bill'; } ], }; __END__ C:\test>junk71 Rate ternary unlessdefined definedor ternary 3989/s -- -45% -53% unlessdefined 7283/s 83% -- -14% definedor 8455/s 112% 16% --

    But as tux says, it's not about speed, it's about convenience, conciseness and readability.

    Performance gain (when measured correctly), is simply a nice side effect.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      I have to ask. Isn't $bill = defined($bill) || 'bill'; the same as the example given above? IIRC, defined returns the scalar value of the expression being tested, which of course is undef when it is not defined. (For those who have not had reason to use it, this is similar to how delete returns the value of the element being deleted, including undef if that was the value or if the element did not exist.)

      Update: DOH!!!! I most certainly did NOT recall correctly! After looking at that again it is obvious that it has to return a Boolean "true" in the case of '0' or ''. The comment regarding delete is correct, but no longer applies in this context. :(

      It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re^2: Make $^V and "my" implicit
by chromatic (Archbishop) on Feb 04, 2014 at 04:13 UTC
    why do people put use 5.010 (or higher) in code that is destined for CPAN

    You're getting everything on the CPAN for free. Why do you expect volunteers to support code that's 18 versions obsolete?

    Please don't assume that others who want to use an otherwise great CPAN module have the environment that will allow them to use anything higher than 5.8 unless there are compelling reasons to disregard those users.

    If they haven't upgraded Perl in the past six years, I have trouble believing they're on the edge of their seats waiting to install the latest version of a module from the CPAN.

      You are right. I, along with many others, get stuff from CPAN for free. That said, some of us do try to return the favor by either contributing back or sharing what knowledge we can. I don't think that invalidates my request that more thought goes into a CPAN module than how many cool, new features can be incorporated that many folks can not use for one reason or another.

      I ask that you bear in mind that there can be outside factors that prevent one from running the latest and greatest at every chance. There are shops out there that still use 5.6 for valid technical reasons, and they are chomping at the bit for those reasons to be removed. Others are on 5.8 for outside reasons, and will change as soon as a 3rd-party vendor makes changes.

      In the meantime, the shops I have direct knowledge of contribute back to CPAN as an acknowledgement of their debt to others as well as take an active part in the Perl community.

      I understand and appreciate the position you stated, and will even grant that there are more than a few who are fully covered by it, but I think you paint with too broad a brush.

      It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
        I don't think that invalidates my request that more thought goes into a CPAN module than how many cool, new features can be incorporated that many folks can not use for one reason or another.

        My code needs working Unicode because I have users who rely on working Unicode. That means at least Perl 5.14—which isn't even supported by p5p anymore.

        There are shops out there that still use 5.6 for valid technical reasons....

        That's fine, but those aren't my reasons and they don't affect me.

        Others are on 5.8 for outside reasons, and will change as soon as a 3rd-party vendor makes changes.

        That's fine, but that vendor's valid technical reasons are even further removed from my concerns. Also the word "vendor" makes me think that someone's getting paid. (I'm not; I'm giving away my code for you to use, modify, distribute, or ignore as you see fit.)

        I've written, tested, documented, and debugged my code. I let you use it for free. I let you redistribute it freely. I let you modify it and redistribute modified versions. In return, all I ask is that do not remove my attribution from it. Is that so much to ask?

        I can't use improvements I've made to Perl itself in the past several years because you have technical concerns that you assure me are valid? Even though they don't apply to me—even though I've given away everything but the credit for writing, testing, documenting, and debugging this code—that's not enough for you?

        What next? If English isn't your first language, is it also my responsibility as a volunteer to translate all of the documentation, comments, and identifiers into everyone's preferred spoken language, because there are valid technical reasons why someone who isn't me (someone who's getting paid to work on this code) uses the local preferred tongue?

        You don't have to be grateful. You don't have to use code I've written. You don't have to care. Even so, I think that telling a volunteer "Sorry, it isn't enough!" is a bit rude.

      If they haven't upgraded Perl in the past six years, I have trouble believing they're on the edge of their seats waiting to install the latest version of a module from the CPAN.

      I may have old Perl versions on some of my servers, that doesn't mean I don't occasionally have to install another CPAN module.

      If that won't work because of some critical feature that simply doesn't exist in my version of Perl, then fine... maybe it's time to upgrade. If, on the other hand, it won't work simply because the author decided to require some fancy, superficial feature like say (because he couldn't be bothered to use print with a "\n"; tacked on), then I would advice that author to switch to Python where nobody seems to care about backwards compatibility.

      Which, btw, is the number reason I won't go near Python.

      -- FloydATC

      Time flies when you don't know what you're doing

        If, on the other hand, it won't work simply because the author decided to require some fancy, superficial feature like say....

        "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?" — Larry Wall

        One person's superficial triviality is a feature that's been in Perl for more than six years now. How long before it's acceptable for volunteers who give away their code freely to use those features? Ten years? Fifteen? If I fix a bug in Perl today and it gets released in 5.20, will I be able to rely on that bug being fixed by 2024? 2029?

        You don't have to upgrade Perl, but you don't have to use any modules I've written either. Even better—you don't have to use them as written. You are more than free to modify them to run on your preferred version. I'll even give you a comprehensive test suite so you can prove that they work to your satisfaction. You can even redistribute the modified version.

        Is that not enough?

Re^2: Make $^V and "my" implicit
by Tux (Canon) on Feb 04, 2014 at 00:16 UTC

    defined-or (or //) is not about speed: it is about logic and concise programming: it improves legibility and maintainability. I use the feature since perl-5.8.0 and it has been a very good reason to upgrade all my perl installations, even with customer sites. I cannot think of writing any perl script that does not use this feature. Silently I still wish the low-precedence keyword err (or dor given a bikeshed argument) will return one happy day.

    Now imagine writing this with ternary:

    my $file = $options{file} // $options{input_file} // get_default_option (""file") // get_default_option ("input_file") + // file_exists ("$ENV{WORK_DIR}/file.in") // file_exists ("$ENV{HOME}/project_in.file") or die;

    Or, preventing warnings

    printf "%-20s: %s\n", $_, $options{$_} // "<undef>" for keys %options; function (map { $_ // "default" } @values); my @sorted = sort { ($a->{order} // 0) <=> ($b->{order} // 0) } @aoh;

    Enjoy, Have FUN! H.Merijn

      Okay, the first example hurts just to look at it. :) But I will agree that overall using //= is more concise, cleaner. My point is that it should not be an overriding factor when writing code that is intended to be used out in the wild in unknown environments.

      The second example (preventing warnings) can just as easily use || and get the same results as //. That said, I have used your example many, many times when writing for a closed environment, mostly for the reasons you give.

      It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

        The second example (preventing warnings) can just as easily use || and get the same results as //. That said, I have used your example many, many times when writing for a closed environment, mostly for the reasons you give.

        No, it cannot, as 0 in most cases is a valid value, very valid. With || it would be replaced.

        Just use it, and see how many unmeant problems suddenly disappear.

        Where || does work well, is when the default for a value is 0, most of which are boolean-like values:

        my $hidden = $cell->{Hidden} || 0;

        true values stay, false values (undef, "", 0 and "0" all get replaced with 0. Replacing 0 with 0 does not hurt.


        Enjoy, Have FUN! H.Merijn

      Now imagine writing this with ternary:

      Why torture yourself?