perl5140delta localized tied variables - perl

perl5140delta says that localized tied variables are no long tied. This change was implemented in 5.13.1 but reverted in 5.13.2. Is this back in 5.14 (from my testing it does not appear to be) or is the delta for 5.14.0 incorrect?
I care because I believe this would break File::chdir which I use regularly.

The perldelta says that localized tied "hashes and arrays" are no longer tied. Scalars are unaffected.
The doc you linked, perl5132delta says:
localised tied scalars are tied again.
The change in behaviour in 5.13.1 of localising tied scalar values has been reverted to the existing 5.12.0 and earlier behaviour (the change for arrays and hashes remains).
The really useful thing I have to say is that you can check your favorite module's status on many versions of Perl using the CPAN Testers service.
Check out the report for File::chdir 0.1004. It passes all of the 5.14 RC tests on different platforms. According to CPANTS you are in good shape.
Of course you could download and build a test version of 5.14 and try it yourself, just to be sure.

Related

How do I change the default ONE_AT_A_TIME_HARD hash function in Perl 5.18?

I'm not really familiar with Perl, but I've been searching in the documentation and other sources without success for the last 2 days. In the documentation, it is written:
Perl v5.18 includes support for multiple hash functions, and changed the default (to ONE_AT_A_TIME_HARD), you can choose a different algorithm by defining a symbol at compile time. For a current list, consult the INSTALL document. Note that as of Perl v5.18 we can only recommend use of the default or SIPHASH. All the others are known to have security issues and are for research purposes only.
The thing is that neither in INSTALL document nor in other sources/sites etc. I can find how to define this symbol.
What I want to do is to change the default ONE_AT_A_TIME_HARD hash function to ONE_AT_A_TIME_OLD so I can simulate the old Perl 5.16 behavior.
This sounds like an XY problem. What are you trying to accomplish by forcibly downgrading the hash algorithm in perl to one that has known problems?
From comments:
I need to run a lot of test cases written in perl 5.16 whose functionality depends on the old hash implementation and it's quite impossible to change the code as the cases are hundreds.
Whew, that's bad news. Find those developers, and hit them around the head with a copy perldata:
Hashes are unordered collections of scalar values indexed by their associated string key.
Specifically - if this is a problem for you, it means your codebase treats hashes as ordered, when they aren't and never were. (It's just they were fairly consistent before 5.18 and more random after).
From perldelta:
When encountering these changes, the key to cleaning up from them is to accept that hashes are unordered collections and to act accordingly.
See: http://blog.booking.com/hardening-perls-hash-function.html
To answer your question - if you really must:
./Configure -DPERL_HASH_FUNC_ONE_AT_A_TIME_OLD -des && make && make test
But it's a very very bad idea, because as the INSTALL file in your perl source package points out:
Note that as of Perl 5.18 we can only recommend the use of default or SIPHASH. All the others are known to have security issues and are for research purposes only.
By building your perl this way you introduce a known security flaw for every perl program using it.
Note - ONE_AT_A_TIME_HARD is the new default, so this won't change how perl 5.18 works. You may mean PERL_HASH_FUNC_ONE_AT_A_TIME_OLD

Perl 5.20 and the fate of smart matching and given-when

I just installed Perl 5.18, and I get a lot of warnings like this,
given is experimental at .\[...].pl line [...].
when is experimental at .\[...].pl line [...].
Smartmatch is experimental at C:/strawberry/perl/site/lib/[...] line [...].
Looking into these warnings -- which I've never heard mentioned anywhere -- I was only able to find this in two places,
perldelta for 5.18, which only really mentions insofar as to say that the feature has been downgraded to experimental?
this nntp.perl.org post
The Perl Delta still does the most to give mention as to what's happening with those features. It's halfway down buried in the pod,
Smart match, added in v5.10.0 and significantly revised in v5.10.1, has been a regular point of complaint. Although there are a number of ways in which it is useful, it has also proven problematic and confusing for both users and implementors of Perl. There have been a number of proposals on how to best address the problem. It is clear that smartmatch is almost certainly either going to change or go away in the future. Relying on its current behavior is not recommended. Warnings will now be issued when the parser sees ~~, given, or when.
I'm confused at how the most significant change in Perl in the past 10 years could be pulled. I've started using given, when, and smartmatch all over the place. Is there any more information about these futures? How is anyone finding them "confusing?" How are these features likely to change? Is there a plan to implement these features with a module?
There are problems with the design of smart-matching. The decision of what any given TYPE ~~ TYPE should do is most often unobvious, inconsistent and/or disputed. The idea isn't to remove smart matching; it's to fix it.
Specifically, ~~ will be greatly simplified, as you can see in a proposal by the 5.18 pumpking. Decisions as to how two things should match will be done with helpers such as those that already exist in Smart::Match.
... ~~ any(...)
It is much more readable, much more flexible (fully extensible), and solves a number of problems (such as "When should X be considered a number, and when should it be considered a string?").
Some insights might be gained by reading rjbs's proposed changes to smartmatch. He is the pumpking (Perl release manager) after all, so his comments and his view of the future is more relevant than most. There is also plenty of community comment on the matter; see here for instance. The 'experimental' status is in effect because, since things are likely to change in the future, it is responsible to inform users of that fact, even if we don't know what those changes will be.
Well, that's what's said in the description of the patch that downgraded this set of features to experimental:
The behavior of given/when/~~ are likely to change in perl 5.20.0:
either smart match will be removed or stripped down. In light of this,
users of these features should be warned. A category
"experimental::smartmatch" warning should be issued for these features
when they are used.
So while you can indeed turn these warnings off, with something like this (source):
no if $] >= 5.018, warnings => "experimental::smartmatch";
... it's just turning your eyes off the problem.

What parts of given/when are experimental?

Has the entire "switch" feature become experimental? Are there parts of it I can rely on using without future versions of Perl breaking my code? In general, what is the policy toward changing stable features to experimental?
Background
use feature "switch" has been in Perl since 5.10. From 5.10 to 5.14, perlsyn seems to indicate that this is a stable, supported feature.
Starting with 5.16, however, perlsyn begins to call it "an experimental switch feature" and gets a lot more confusing about what's considered experimental.
Parts of the documentation seem to indicate everything about the feature is experimental:
Under the "switch" feature, Perl gains the experimental keywords given, when, default, continue, and break.
There's even an entire section about the Experimental Details on given and when.
However, perlsyn also says that "The foreach is the non-experimental way to set a topicalizer" and gives an example that seems to imply that foreach/when is not experimental.
As far as I can tell, the "experimental" language came from commit c2f1e22 which references RT #90926 which still doesn't give much context, even when paired with RT# 90906.
Has the entire "switch" feature become experimental?
No. It has always been.
Upd: Oh wow, maybe I'm wrong. I can't find a mention of that in 5.10.0 or .1. Maybe it wasn't? Or maybe they forgot to note it? Either way, it seems they messed up worse than I thought if so! But based on what I've seen since, I think the lesson was learned. (e.g. I still think values $ref is a bad idea, but at least it was marked experimental from day
1.)
Are there parts of it I can rely on using without future versions of Perl breaking my code?
Technically, no, although the devs are always careful when it comes to backwards compatibility.
In general, what is the policy toward changing stable features to experimental?
I don't see that ever happening. The deprecation process would be used instead.
Changes so far:
given is changing from creating a lexical $_ to localising $_ like foreach loops in 5.18 (or did it already happen in 5.16?).
5.10.1 saw some big changes in smart-matching*. Don't use (smart-matching in) 5.10.0.
Possible future changes:
The behaviour of smart-matching* is still a hot topic.
* — True, this is a feature distinct from given-when, but it's the same or closely related in most people's minds.

How should I control versions of my Perl Moose objects?

I'm a Moose newbie and I wonder if the common
our $VERSION = "0.001";
$VERSION = eval $VERSION;
should also be used in Moose packages, or Moose has some alternative way for version control. Couldn't find a reference in Moose docs.
As with all perl packages, it is usually a good idea to have a $VERSION defined in them. This allows other things to properly depend on the version of them with all the features they need, either by declaring a dependency in their Makefile.PL or equivalent, or directly when loading the module using use SomeModule 1.23;.
The eval construct you're showing is a kludge. There is a distinction between regular releases of a module, and development releases. Traditionally that has been indicated by a $VERSION with an underscore in it. That means something like 0.001 would be a normal, stable release, while something like 0.001_01 would be a development release.
The eval is used to get rid of that underscore at runtime, while still preserving it in the version string that the various tools, including PAUSE, the Perl Authors Upload SErver, extract. This is to avoid warnings such as 0.001_01 is not numeric in ....
You'll find that idiom in lots of code. Luckily, there's a good alternative to it. Instead of indicating the development vs. non-development status in the version number of individual modules, you can also do that in the release tarball that you might upload to CPAN by using the -TRIAL flag.
Instead of uploading your distribution as My-Distribution-0.001.tar.gz, you can rename it to My-Distribution-0.001-TRIAL.tar.gz. The CPAN tools will pick that up and treat it as a development release accordingly. Note that -TRIAL is not part of the $VERSION, only of the tarball name. Therefore the eval kludge becomes unnecessary.
Also note that there are alternative ways to declare a package's $VERSION. As of perl 5.12.0, you are able to declare it right with in the package declaration:
package My::Package 0.001;
However, none of this is specific to Moose in any way.

What's the modern way of declaring which version of Perl to use?

When it come to saying what version of Perl we need for our scripts, we've got options, oh, brother, we've got options:
use 5.010;
use 5.010_001;
use 5.10.0;
use v5.10;
use v5.10.0;
All seem to work. perlcritic complains about all but the first two. (It's unfortunate that the v strings seem to have such flaws, since Perl 6 expects you to do use v6; for your Perl 6 scripts...)
So, what should we be doing to indicate that we want to use a particular version of perl?
There are really only two options: decimal numbers and v-strings. Which form to use depends in part on which versions of Perl you want to "support" with a meaningful error message instead of a syntax error. (The v-string syntax was added in Perl 5.6.) The accepted best practice -- which is what perlcritic enforces -- is to use decimal notation. You should specify the minimum version of Perl that's required for your script to behave properly. Normally that means declaring a dependency on language features added in a major release, such as using the say function added in 5.10. You should include the patch level if it's important for your script to behave properly. For example, some of my code specifies use 5.008001 because it depends on the fix for a bug that 5.8.0 had which was fixed in 5.8.1.
I just use something like 5.010_001. I've grow weary of dealing with version string problems for something that should be mind-numbingly simple.
Since I mostly deal with build systems, I have the constant struggle of Module::Build's internal version.pm which is out of sync with the version.pm on CPAN. I think that's mostly better now, but I have better things to think about.
The best practice should always be to do the thing that commands the least of your attention, and certainly not take more attention than the value it gives back. In my opinion, v-strings and dotted decimals were a huge distraction with no additional benefit, wasting a lot of valuable programmer time just to get back to the starting point.
I should also note that Perl::Critic has often pushed questionable practices for the higher purpose of reducing the ways that people do things. However, those practices often cause problems, make them un-best. This is one of those cases. A more realistic best practice is to not make Perl::Critic compliance your goal. Use it where it is useful, but in cases like this, don't waste mental time on it.
The "modern" way is to use the forms starting with v. However, that may not necessarily be what you really want to do.
Critic complains because older versions of Perl won't understand and play nicely with the forms that start with v. However, if your version of Perl supports it, v is nicer to read because you can say:
use v5.10.1;
... rather than ...
use 5.010_001;
So, in the documentation for use, the following workaround is offered:
use 5.006; use v5.6.1;
NB: I think the documenation is in error here, as the v is omitted from the example at perldoc use.
Since the versions of Perl that don't support the v syntax will fail at the first use, they won't get to the second more specific and readable one.