There's more than one way to do things PerlMonks

### Re: One out of three ain't bad (order)

by tye (Sage)
 on Oct 22, 2005 at 05:49 UTC ( #502182=note: print w/replies, xml ) Need Help??

in reply to One out of three ain't bad

Avoid the obfuscating punctuation:

```if( 1 == grep \$_, \$x, \$y, \$z )

Or, using a more versatile trick:

```if( 1 == !!\$x + !!\$y + !!\$z )

But note that some will kvetch that the fact of !0 == 1 is "not defined" in Perl. But that ship has already sailed; practicality actually prevents Perl from changing the value of "true" to something other than 1, even if this property was intentionally left undefined.

- tye

Replies are listed 'Best First'.
Re^2: One out of three ain't bad (order)
by ph713 (Pilgrim) on Oct 22, 2005 at 08:42 UTC
I like this !! based solution the best. It's the most logical way to solve the problem - convert the arguments to boolean truth values, then sum them. You could do it for an arbitrarily long list of variables with:
```use List::Util qw( sum );

if( 1 == sum( map { !!\$_ } @inputs) ) {
...
}

As long as you're going to go through the same code path for each element in the array anyway, why not de-obfuscate that a bit and use the ternary operator?

```if (1 == sum( map { \$_ ? 1 : 0 } @inputs ))
While tye may be right that, in practice, Perl can't change the value of !0, I just don't like relying on obscure implementation details when clear, well-defined implementation details are available to me to accomplish the same thing in a readable, understandable, and maintainable manner.

Why are you using sum instead of grep here? If you are summing 1 and 0 then the sum will always be the same as the grep answer. For what it's worth I woul disagree that (\$_ ? 1 : 0) is clearer in anyway than !!\$_. To me the !! version yells bool, while I had to read the ?: version twice before comprehension came. That might be in part because Perl6's new bool context (don't shoot me if that isn't the right wording) lets you ask for a true/false value explicity so thats what I would expext !! to do.

___________
Eric Hodges
Re^2: One out of three ain't bad (order)
by Dr. Mu (Hermit) on Oct 23, 2005 at 04:21 UTC
Or, shorter:

if (2 == !\$x + !\$y + !\$z) {

Which seems to work right now, since you've seen the progression of what came before. But in 2 months, I can imagine you thinking, "Now why in the world is there a two in there... I must want two of them to be true" on your first look while skimming your code.

-Bryan

True enough. I suppose what's lacking is a commonly-accepted idiom for Boolean conversions. We have 0+ for numeric conversions; so perhaps !! wasn't so bad after all, even though two operations are implied (unless the compiler optimizes them out). 0|| and 1&& would also work.

Create A New User
Node Status?
node history
Node Type: note [id://502182]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2018-02-24 07:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When it is dark outside I am happiest to see ...

Results (310 votes). Check out past polls.

Notices?