Two operations with one last if?

B

Brian McCauley

sam said:
Is the following "legal" and "sensible?"
while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) = split(/\?/,$archivesection,2);
$userid = $searchpattern{$interestingpart} && $splinter =
$_, last if(defined($searchpattern{$interestingpart}))

if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;
}
}

While it is legal to fail to declare all your variables as lexically
scoped in the smallest applicable scope it is cetainly not sensible to
do so without a positive reason.

While it is legal to use the Perl4 subroutine calling convention is not
sensible to do so without a positive reason.

While it is legal to use shared variables to pass information between a
subroutine and its caller is not sensible to do so without a positive
reason.

It is legal to save the result of a short expression into a variable
whose name is longer than the expression and then only use that variable
once ($archivesection,@record). It is, of course, not sensible.

It is legal to store data you don't want into a variable you never use
again ($junk). It is, of course, not sensible. (Just don't save it).

It is legal to use && and , to combine multiple expressions into one so
that they can be goverened by a single 'if' statement qualifier. It
can sometimes even be sensible to do so where it aid readability.

It is not legal to attempt to assign to the result of an && opreator. To
get "Can't modify logical and (&&) in scalar assignment".

I shall assume '&&' should read 'and' or ','.

However once it gets above a very small number of characters it would be
more sensible just to use a proper 'if' statement.

It is legal to have a variable with a name (%searchpattern) that doesn't
contain patterns. It is not sensible.

While it is legal to put unreachable code in your programs it is rarely
sensible. I'm 98% sure that condition defined($splinter) can never be
true. If you eschewed the obfuscatation this would be more obvious.
 
P

Paul Lalli

sam said:
Is the following "legal" and "sensible?"

while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) = split(/\?/,$archivesection,2);
$userid = $searchpattern{$interestingpart} && $splinter =
$_, last if
(defined($searchpattern{$interestingpart}))

Why would you want to use such a nasty syntax?

if (defined $searchpattern{$interestingpart}){
$userid = $searchpattern{$interestingpart}
$splinter = $_;
last;
}

Saving a few keystrokes (or even a few lines) is not a justifiable
reason to sacrifice the readability of your code.
if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;

Why are you using all of those ampersands? Do you actually want the
sideaffects they give? If not, lose them. Read
perldoc perlsub
for more info.



Paul Lalli
 
U

Uri Guttman

BM> I shall assume '&&' should read 'and' or ','.

i now follow the rule (from peter scott) to use &&/|| in logical
expressions and and/or for logical flow control (as in open or die). it
makes more sense and it usually matches the precedence very well.

so with the multiple assignment i would agree to use and or , but a
proper if block would be clearer IMO. that statement has 3 complete
statements in it and is hard to read.

uri
 
S

sam

Is the following "legal" and "sensible?"

while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) = split(/\?/,$archivesection,2);
$userid = $searchpattern{$interestingpart} && $splinter =
$_, last if (defined($searchpattern{$interestingpart}))

if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;
}
}

I want the userid from the associative array and the record that
belongs to that userid if I find the piece I'm looking for in that
record. Or is there another/better way to do this?
 
B

Brian McCauley

Uri said:
BM> I shall assume '&&' should read 'and' or ','.

i now follow the rule (from peter scott) to use &&/|| in logical
expressions and and/or for logical flow control (as in open or die).

Me too!
so with the multiple assignment i would agree to use and or , but a
proper if block would be clearer IMO. that statement has 3 complete
statements in it and is hard to read.

Yes, I also made that point elsewhere in my response.
 
S

Steve R.

<posted & mailed>
Is the following "legal" and "sensible?"

while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) =
split(/\?/,$archivesection,2); $userid =
$searchpattern{$interestingpart} && $splinter =
$_, last if
(defined($searchpattern{$interestingpart}))

if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;
}
}

I want the userid from the associative array and the record that
belongs to that userid if I find the piece I'm looking for in that
record. Or is there another/better way to do this?

It's certainly "legal". It might be a bit more readable to write

if (defined($searchpattern{$interestingpart})) {
$splinter = $_ if $userid = $searchpattern{$interestingpart};
last;
}

assuming you really meant the conditional, or else just

if (defined($searchpattern{$interestingpart})) {
$userid = $searchpattern{$interestingpart};
$splinter = $_;
last;
}
 
S

Steve R.

<posted & mailed>
Is the following "legal" and "sensible?"

while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) =
split(/\?/,$archivesection,2); $userid =
$searchpattern{$interestingpart} && $splinter =
$_, last if
(defined($searchpattern{$interestingpart}))

if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;
}
}

I want the userid from the associative array and the record that
belongs to that userid if I find the piece I'm looking for in that
record. Or is there another/better way to do this?

It's certainly "legal".  It might be a bit more readable to write

    if (defined($searchpattern{$interestingpart})) {
 $splinter = $_ if $userid = $searchpattern{$interestingpart};
 last;
    }

assuming you really meant the conditional, or else just

    if (defined($searchpattern{$interestingpart})) {
 $userid = $searchpattern{$interestingpart};
 $splinter = $_;
 last;
    }
 
S

Steve R.

<posted & mailed>
<posted & mailed>
Is the following "legal" and "sensible?"

while(<LOGFILE>) {
undef($splinter);
@record = split;
$archivesection = $record[6];
($interestingpart, $junk) =
split(/\?/,$archivesection,2); $userid =
$searchpattern{$interestingpart} && $splinter =
$_, last if
(defined($searchpattern{$interestingpart}))

if (defined($splinter) &&
(&daily || &weekly || &monthly || &yearly)) {
&add_splinter_to_pile;
}
}

I want the userid from the associative array and the record that
belongs to that userid if I find the piece I'm looking for in that
record. Or is there another/better way to do this?

It's certainly "legal". It might be a bit more readable to write

if (defined($searchpattern{$interestingpart})) {
$splinter = $_ if $userid = $searchpattern{$interestingpart};
last;
}

assuming you really meant the conditional, or else just

if (defined($searchpattern{$interestingpart})) {
$userid = $searchpattern{$interestingpart};
$splinter = $_;
last;
}

---------
Steve R.
Flamingo
Computers
---------

sorry, my newsreader messed up
 
D

David K. Wall

Uri Guttman said:
i now follow the rule (from peter scott) to use &&/|| in logical
expressions and and/or for logical flow control (as in open or
die). it makes more sense and it usually matches the precedence
very well.

Do you have a reference for that? I generally use 'and' and 'or' and
enforce my desired precedence with parens, but I'm willing to be
persuaded otherwise.
 
U

Uri Guttman

DKW> Do you have a reference for that? I generally use 'and' and 'or' and
DKW> enforce my desired precedence with parens, but I'm willing to be
DKW> persuaded otherwise.

you do know that &&/|| are the exact same operations as and/or but with
tighter binding? all of them short circuit too.

using parens to control is just added noise IMO. but that depends on the
location of the parens too.

i still tend to use parens with open:

open( BLAH ... ) || die 'slowly' ;

the () are needed there. that could also be written (horribly) as:

( open BLAH ... ) || die 'slowly' ;

most perl hackers seem to be dropping the () and using or. this fits the
rule as this is flow control.

open BLAH ... or die 'faster' ;

but when you get into expressions, you usually want the tighter
binding. this works as expected:

my $foo = $bar || $default ;

but this doesn't:

my $foo = $bar or $default ;

adding parens fixes it but at a cost of noise:

my $foo = ( $bar or $default ) ;

&&/|| work well in expressions since their binding is higher than
assignment. and/or work well in flow control since their binding is
lower than assignment

$foo = $bar or print "[$bar] isn't true\n" ;

that does what you think it would do. this doesn't:

$foo = $bar || print "[$bar] isn't true\n" ;

that will print but also assign 1 (the return value of print) to $foo
when $bar is false .

so choose your boolean ops wisely. you may save someone's life! :)

uri
 
D

David K. Wall

Uri said:
DKW> Do you have a reference for that? I generally use 'and' and
DKW> 'or' and enforce my desired precedence with parens, but I'm
DKW> willing to be persuaded otherwise.

you do know that &&/|| are the exact same operations as and/or
but with tighter binding? all of them short circuit too.

Yes, I knew that.


[snip]
but when you get into expressions, you usually want the tighter
binding. this works as expected:

my $foo = $bar || $default ;

And is what I would normally write....

but this doesn't:

my $foo = $bar or $default ;

adding parens fixes it but at a cost of noise:

my $foo = ( $bar or $default ) ;

I'm not sure I'd even thought of writing something like this. :)

&&/|| work well in expressions since their binding is higher than
assignment. and/or work well in flow control since their binding
is lower than assignment

Ok, I see what you mean now. I was thinking along the lines of

if ($foo eq 'bar' or $foo eq 'baz') {
# do something
}

In this simple case I see little reason to prefer || to or, although
I'm sure you could come up with an example where || is the better
choice.

$foo = $bar or print "[$bar] isn't true\n" ;

that does what you think it would do. this doesn't:

$foo = $bar || print "[$bar] isn't true\n" ;

that will print but also assign 1 (the return value of print) to
$foo when $bar is false .

Heh. I would look at that code and decide that I was trying to be too
clever, and rewrite it. I don't spend all day every day writing Perl
code, so what code I do write I try to make easy for me to read
months or years later when I need to update something.
so choose your boolean ops wisely. you may save someone's life!
:)

Or some monkey's life. :)
 
U

Uri Guttman

DKW> Yes, I knew that.

some of that was meant for the whole thread, not just you.

DKW> I'm not sure I'd even thought of writing something like this. :)

but you said before:

DKW> Do you have a reference for that? I generally use 'and' and
DKW> 'or' and enforce my desired precedence with parens, but I'm
DKW> willing to be persuaded otherwise.

so that example was doing what you said :)


DKW> Ok, I see what you mean now. I was thinking along the lines of

DKW> if ($foo eq 'bar' or $foo eq 'baz') {
DKW> # do something
DKW> }

that is still an expression. ||/&& has always bound tighter than the
comparision ops since they are meant to join those into larger boolean
expressions. this is classic precedence stuff in many languages.

DKW> In this simple case I see little reason to prefer || to or, although
DKW> I'm sure you could come up with an example where || is the better
DKW> choice.

i think you meant 'or' instead of the last '||'.

but here is a possible example. i like to assign stuff from a hash to a
scalar and test it at the same time. something like this:

if ( my $foo = $href->{foo} and my $bar = $href->{bar} ) {

# use $foo and $bar
}

&& will fail miserably there and the extra parens needed will be noisy.

note that $foo and $bar are scoped to the block. i do that so i can use
the data inside the block and not have to do a hash access each time. i
don't recall doing 2 of them like that but i do the single assign/test
often. many times the value is another hash ref and it is used multiple
times so saving the higher level deref is faster and cleaner as well.

if ( my $foo_ref = $href->{foo} ) {

do stuff with $foo_ref
}

uri
 
D

David K. Wall

Uri Guttman said:
DKW> if ($foo eq 'bar' or $foo eq 'baz') {
DKW> # do something
DKW> }

that is still an expression. ||/&& has always bound tighter than
the comparision ops since they are meant to join those into
larger boolean expressions. this is classic precedence stuff in
many languages.

I think I'll quit while I'm behind. I understand what you mean, but
my brain keeps insisting on the wrong interpretation. :)
 

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

Forum statistics

Threads
474,163
Messages
2,570,897
Members
47,436
Latest member
MaxD

Latest Threads

Top