Concise idiom sought

D

Dave

I have the following code snippet:

if ( !defined $base_ref->{pl} ) {
$base_ref->{pl} = 1;
}

following the 'Best practices' guidelines. Previously I had it as:

$base_ref->{pl} = 1 unless defined $base_ref->{pl};

which seems clearer to me...

In bash shell scripting there is the ${variable:=default} idiom. I
understand that Perl 6 will have something similar. Is there anything in
Perl 5 that is better than my three lines above and still within the Best
Practices guidelines?

Thanks

Dave
 
P

Peter Scott

I have the following code snippet:

if ( !defined $base_ref->{pl} ) {
$base_ref->{pl} = 1;
}

following the 'Best practices' guidelines. Previously I had it as:

$base_ref->{pl} = 1 unless defined $base_ref->{pl};

which seems clearer to me...

Then use it. The PBP guidelines are suggestions, not straitjackets.

Personally, I would write it as

$base_ref->{pl} ||= 1;

unless you have some need to distinguish between false and undefined
values.
 
A

Anno Siegel

Dave said:
I have the following code snippet:

if ( !defined $base_ref->{pl} ) {
$base_ref->{pl} = 1;
}

following the 'Best practices' guidelines. Previously I had it as:

$base_ref->{pl} = 1 unless defined $base_ref->{pl};

which seems clearer to me...

If it seems clearer to you, by all means write it that way. PBP isn't
meant to be binding for all Perl coders everywhere, it is a set of
guidelines to use when defining a coding style.
In bash shell scripting there is the ${variable:=default} idiom. I
understand that Perl 6 will have something similar. Is there anything in
Perl 5 that is better than my three lines above and still within the Best
Practices guidelines?

Perl 5.10.x will have the //= operator for exactly that purpose. (There
is also a patch available that adds it to current Perl.)

$base_ref->{pl} //= 1;

Sometimes, depending on the range of values in the hash,

$base_ref->{pl} ||= 1;

That works if all valid values are boolean true, for instance if they
are references.

Otherwise, these do the same thing:

defined( $base_ref->{pl}) || $base_ref->{pl} = 1;
defined || $_ = 1 for $base_ref->{pl};

Anno
 
I

it_says_BALLS_on_your_forehead

Dave said:
I have the following code snippet:

if ( !defined $base_ref->{pl} ) {
$base_ref->{pl} = 1;
}

following the 'Best practices' guidelines. Previously I had it as:

$base_ref->{pl} = 1 unless defined $base_ref->{pl};

which seems clearer to me...

In bash shell scripting there is the ${variable:=default} idiom. I
understand that Perl 6 will have something similar.

yes, it would be:
$pi //= 3;

which is the equivalent of

defined($pi) ?? $pi :: 3;

(the trinary operator is doubling up since it's essentially a short
circuit operator and should look its part, and also b/c that way it's
more in tune with efficient Huffman Coding)


Is there anything in
Perl 5 that is better than my three lines above and still within the Best
Practices guidelines?

really it's a matter of preference, and what makes sense in your head,
as well as what you think will be easiest to maintain for your current
team and future members of your team (which you really will never
know).

# if you don't like the smell of 'unless', try this...
defined $base_ref->{pl} or $base_ref->{pl} = 1;
 
D

Dr.Ruud

Dave schreef:
I have the following code snippet:
C<if ( !defined $base_ref->{pl} ) { $base_ref->{pl} = 1 }>
following the 'Best practices' guidelines. Previously I had it as:
C<$base_ref->{pl} = 1 unless defined $base_ref->{pl}>
which seems clearer to me...

(some whitespace compressed)

$ perl -MO=Deparse,-x7 -e 'if (!defined $x) {$x=1}'
not defined $x and do { $x = 1 };


$ perl -MO=Deparse,-x7 -e 'unless (defined $x) {$x=1}'
defined $x or do { $x = 1 };



$ perl -MO=Deparse,-x7 -e '$x = 1 unless defined $x'
defined $x or $x = 1;


Is there anything
in Perl 5 that is better than my three lines above and still within
the Best Practices guidelines?

$x ||= 1;
 
D

Dave

Dr.Ruud said:
Dave schreef:


(some whitespace compressed)

$ perl -MO=Deparse,-x7 -e 'if (!defined $x) {$x=1}'
not defined $x and do { $x = 1 };


$ perl -MO=Deparse,-x7 -e 'unless (defined $x) {$x=1}'
defined $x or do { $x = 1 };



$ perl -MO=Deparse,-x7 -e '$x = 1 unless defined $x'
defined $x or $x = 1;




$x ||= 1;

--
Affijn, Ruud

"Gewoon is een tijger."
echo 014C8A26C5DB87DBE85A93DBF |perl -pe 'tr/0-9A-F/JunkshoP cartel,/'

Thanks everyone for these answers. In this case 0 is a valid value, so the
||= construct is not suitable (although I think it is the clearest and most
concise when it is). While waiting for //= to be implemented in mainstream
Perl and become widespread I think I'll use:

defined $base_ref->{pl} or $base_ref->{pl} = 1;

Thanks again for all your suggestions
 
D

Dave

Abigail said:
Dave ([email protected]) wrote on MMMMDLXXXIX September MCMXCIII
in <URL:__ I have the following code snippet:
__
__ if ( !defined $base_ref->{pl} ) {
__ $base_ref->{pl} = 1;
__ }
__
__ following the 'Best practices' guidelines. Previously I had it as:
__
__ $base_ref->{pl} = 1 unless defined $base_ref->{pl};
__
__ which seems clearer to me...


Replacing something which is correct and not inefficient with something
else that's correct and also not inefficient, but less clear to yourself
is, IMO, very very stupid.

Doing something one way for no other reason it is in PBP is, IMO, very
very
stupid, and a sign you didn't understand PBP.

You certainly didn't read, or didn't understand the introduction (chapter
1).


Go read the book again. Chapter 1. Middle paragraph of page 6.

Do not advance and certainly don't implement anything of the book until
you fully understand that paragraph.

It's the most important paragraph of the book.



Abigail
--
perl -MTime::JulianDay -lwe'@r=reverse(M=>(0)x99=>CM=>(0)x399=>D=>(0)x99=>CD=>(
0)x299=>C=>(0)x9=>XC=>(0)x39=>L=>(0)x9=>XL=>(0)x29=>X=>IX=>0=>0=>0=>V=>IV=>0=>0
=>I=>$==-2449231+gm_julian_day+time);do{until($=<$#r){$_.=$r[$#r];$=-=$#r}for(;
!$r[--$#r];){}}while$=;$,="\x20";print+$_=>September=>MCMXCIII=>=>=>=>=>=>=>=>'

Mmm, I have read the whole book and am going through it again. I have not
blindly implemented any of the guidelines. In this case I agree with the
rationale given in PBP for avoiding both of the 'problems' with my original
code. What I didn't like was the longwindedness of my own rewrite in terms
of 'if (!defined...) {...}'. The 'defined...or...' construct fixes this
perfectly. The //= operator is even better.

Dave
 
U

Uri Guttman

isBoyf> $pi //= 3;

isBoyf> which is the equivalent of

isBoyf> defined($pi) ?? $pi :: 3;

not really as the first is an assignment and the second isn't. drop the
= to make them the same (just expressions).

uri
 
I

it_says_BALLS_on_your_forehead

Uri said:
isBoyf> $pi //= 3;

isBoyf> which is the equivalent of

isBoyf> defined($pi) ?? $pi :: 3;

not really as the first is an assignment and the second isn't. drop the
= to make them the same (just expressions).

ahh, good catch. thanks.
 
U

Uri Guttman

isBoyf> ahh, good catch. thanks.

and i think the syntax of p6's ?: has changed (again!) to ?? !!. the !!
is nice as it marks the value to use if the condition is false:

my $val = $expr ?? $true !! $false ;

but i would double (triple!) check the p6 synopses before you go coding
that.

uri
 
R

robic0

I have the following code snippet:

if ( !defined $base_ref->{pl} ) {
$base_ref->{pl} = 1;
}

following the 'Best practices' guidelines. Previously I had it as:

$base_ref->{pl} = 1 unless defined $base_ref->{pl};

which seems clearer to me...

In bash shell scripting there is the ${variable:=default} idiom. I
understand that Perl 6 will have something similar. Is there anything in
Perl 5 that is better than my three lines above and still within the Best
Practices guidelines?

Thanks

Dave

I'm going to say this only once. You have an "if/then" construct.
There is *NO* construct closer to the *CPU* in any representation.

No matter how you want to classify it in abstract terms, any substitute
construct will resolve to the simplicity of your original lines.

I've continually harped on this to no avail. As the goddamed "nerve"
of some utterly brain dead individuals that post on this group to post
some absolute *CRAP* substitution to a basic if/then condition.

If anone cares to benchmark a stupid 1 liner and compare it to a
low level if/then construct. Please do so.

Otherwise, all you lame-brained respondents to this post are entirely
"full o shit" !!!

I welcome a benchmark to prove otherwise.
The fact is, the if/then, the if having a not (!) is 'C' style and its
closest to the cpu. That simple construct is not there by accident.

To the bullshit posted by the others here.. As posted above, make a
looping binary with the simple if/then, run a bench on it.
Then do the same in a Perl program. Then do one in 'C'. Compare the
results.

It's almost impossible to control the profanity in this case..

robic0
as posted
 
R

robic0

I'm going to say this only once. You have an "if/then" construct.
There is *NO* construct closer to the *CPU* in any representation.

No matter how you want to classify it in abstract terms, any substitute
construct will resolve to the simplicity of your original lines.

I've continually harped on this to no avail. As the goddamed "nerve"
of some utterly brain dead individuals that post on this group to post
some absolute *CRAP* substitution to a basic if/then condition.

If anone cares to benchmark a stupid 1 liner and compare it to a
low level if/then construct. Please do so.

Otherwise, all you lame-brained respondents to this post are entirely
"full o shit" !!!

I welcome a benchmark to prove otherwise.
The fact is, the if/then, the if having a not (!) is 'C' style and its
closest to the cpu. That simple construct is not there by accident.

To the bullshit posted by the others here.. As posted above, make a assembly compiled binary
looping binary with the simple if/then, run a bench on it.
Then do the same in a Perl program. Then do one in 'C'. Compare the
results.

It's almost impossible to control the profanity in this case..

robic0
as posted
 
R

Randal L. Schwartz

Dave> I have the following code snippet:
Dave> if ( !defined $base_ref->{pl} ) {
Dave> $base_ref->{pl} = 1;
Dave> }

Dave> following the 'Best practices' guidelines. Previously I had it as:

Dave> $base_ref->{pl} = 1 unless defined $base_ref->{pl};

Dave> which seems clearer to me...

I don't like repeating the expensive "find the lvalue" stuff. If there's a
complex calculation to get to the variable, do it just one, please.

I'd write that as:

defined $_ or $_ = 1 for $base_ref->{pl};

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[email protected]> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
*** Free account sponsored by SecureIX.com ***
*** Encrypt your Internet usage with a free VPN account from http://www.SecureIX.com ***
 
D

Dr.Ruud

Randal L. Schwartz schreef:
defined $_ or $_ = 1 for $base_ref->{pl};

Alternatively:

{ local $_; defined or $_ = 1 for $v }

{ local $_ = \$v; defined $$_ or $$_ = 1 }
 
D

Dr.Ruud

Anno Siegel schreef:
Dr.Ruud:

Where has $v come from?

It is just a replacement for the $base_ref->{pl}
Does $v suffer much less from the <expensive "find the lvalue"> blues
than $v, making it an invalid stand-in?

You don't need local() here. The assignment through "for" is
instrinsically localized.

Thanks, I didn't realize that while playing with several alternatives.

In perlsyn, it isn't stated explicitly that, inside a foreach, $_ is or
isn't local:
"If VAR is omitted, $_ is set to each value."
Especially because the behaviour of my-declared variables is explained
in detail, I fear that one might get from this text that $_ doesn't get
the same treatment. My proposal:
"If VAR is omitted, a local $_ is set to each value.".
"If VAR is omitted, the localized $_ is set to each value.".
 
A

Anno Siegel

Dr.Ruud said:
Anno Siegel schreef:

It is just a replacement for the $base_ref->{pl}
Does $v suffer much less from the <expensive "find the lvalue"> blues
than $v, making it an invalid stand-in?

Well, it's a simple variable, I don't see a reason to alias it to another
simple variable. With arrays and hashes, access to an element is a
two-step process, so "... for $base_ref->{pl}" saves a step for each
time $_ is used on the left side.

Too bad it doesn't work with exists() and delete(), but that would take
more than an lvalue.

Anno
 
D

Dr.Ruud

Anno Siegel schreef:
Dr.Ruud:

Well, it's a simple variable, I don't see a reason to alias it to
another simple variable.

I agree, I lost meaning in my simplification.

With arrays and hashes, access to an
element is a two-step process, so "... for $base_ref->{pl}" saves a
step for each time $_ is used on the left side.

Too bad it doesn't work with exists() and delete(), but that would
take more than an lvalue.

Ack.
 
T

Tim Kazner

Randal L. Schwartz schreef:


Alternatively:

{ local $_; defined or $_ = 1 for $v }

{ local $_ = \$v; defined $$_ or $$_ = 1 }

1. $$v=1 if (!defined $v=\$base_ref->{pl});
2. if (!defined $base_ref->{pl}) {
$base_ref->{pl} = 1;
}

Would seem 1. incurrs an overhead assignment
that 2. doesen't if $base_ref->{pl} is defined.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top