Forum Moderators: coopster & phranque

Message Too Old, No Replies

How do we feel about experimental stuff?

Specifically, should I use given / when?

         

csdude55

12:22 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since switch/case no longer exists, the recommendation is to use given/when; eg,

given ($foo) {
when ($bar || $example) { print 'yes'; }
default { print 'no'; }
}


But when testing on jdoodle, I'm seeing that I HAVE to use use 5.22.0 (the lowest version they have) or I get an error. And it still warns "given is experimental".

Having to select a Perl version bugs me; when I update Perl, am I going to have to modify all of my scripts? Why does it matter, anyway? I have v. 5.16.0 installed, if it recognizes given/when then why do I have to tell it to use 5.16.0?

What's the general consensus on using "experimental" things like given/when, anyway? I certainly hate to build it and then find out that it's removed in a future version :-O

phranque

2:59 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



probably best to use foreach instead for reasons described here:
https://perldoc.perl.org/perlsyn#Switch-Statements

csdude55

3:56 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The docs aren't clear on foreach. The example uses for ($var), but then it says to use foreach without an example. Is it just this?

# instead of declaring a specific version, so I guess that's better
use feature "switch";

foreach ($foo) {
when ($bar || $example) { print 'yes'; }
default { print 'no'; }
}


What's the advantage to using foreach() instead of for()?

My goal is to improve on a series of lines like this:

if (
$foo eq 'bar' ||
$foo eq 'lorem' ||
$foo eq 'ipsum' ||
$foo eq 'this' ||
$foo eq 'that') { print 'yes'; }


This actually processes a little faster, but it's ugly (especially when the value has a space):
if ($foo =~ m{^(
bar |
lorem |
ipsum |
this |
that
)$}x) { print 'yes'; }


In theory, this would be the fastest way to process it:
for ($foo) {
when (
'bar' ||
'lorem' ||
'ipsum' ||
'this' ||
'that') { print 'yes'; }


Thoughts?

csdude55

4:24 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Well, since I mentioned speed, it turns out that the regex is by far the fastest, for / when is second, and a series of $foo eq 'bar' is the slowest. Over 10,000 iterations:

for / when: 0.00189113616943359
regex: 0.000795125961303711
eq: 0.00346493721008301

But I might still want to use the for / when for (a) readability, and (b) to not have to worry about spaces or escaping accidental regex code (like a . or *). Unless you all think it's a bad idea to use, since it's experimental?

phranque

6:02 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



it turns out that the regex is by far the fastest

pretty sure i've mentioned this before but regex engines (especially in perl) are likely to be highly optimized

phranque

6:08 am on Sep 29, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The docs aren't clear on foreach. The example uses for ($var), but then it says to use foreach without an example.
...
What's the advantage to using foreach() instead of for()?

The foreach keyword is actually a synonym for the for keyword, so you can use either.

(source: https://perldoc.perl.org/perlsyn#Foreach-Loops)

csdude55

6:00 pm on Sep 29, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



pretty sure i've mentioned this before but regex engines (especially in perl) are likely to be highly optimized

You did, and that's what led me to using the regex in the first place :-)

But I run into a minor issue when using /x and the variable has a space, so I don't "love" it. Meaning, let's say that $foo = 'this and that';. I have to use /this.and.that/ in the regex, which might match "this-and-that" when I don't want it to.

Or, more commonly, I open the script to see if I've mentioned "this and that" anywhere, and have to remember to search for "this and that", "this.and.that", "this.*?that", and "this\W?and\W?that", etc.

Because of those, I'm leaning back towards not using regex; the performance boost isn't worth the extra work on my end.

Now that I'm working with the sun up, though, it's not working like I expected after all!

use feature 'switch';

$foo = 'lorem';

for ($foo) {
when (
'bar' ||
'lorem'
) { print 'yes'; }

default { print 'no'; }
}


I'm expecting 'yes', but get 'no'. If I change it to $foo = 'bar'; , though, then I get 'yes'.

So maybe it doesn't work quite like I thought, after all? If I have to do this then it totally defeats the purpose:

for ($foo) {
when ('bar') { print 'yes'; }
when ('lorem') { print 'yes'; }

default { print 'no'; }
}


Speed testing using a series of "when" for each condition and no match, it's 4 time slower than "eq".

Making it match the first condition, "when" is 2 times slower than "eq".

Making it match the last condition, it's 3 times slower than using "eq".