# Neat way of checking that two hash values both exist?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
I'm checking parameters to a little utility I'm writing.  It uses
Getopt::Std, which returns the parameters in a hash %opts.

The logic of the utility requires both flags -h and -p to be specified
or neither.  I'm coding the part that checks whether that is true.

I'm sure there's a neater way than this (which does work, admittedly):

die "Flags -h and -p must be specified together\n"
if (exists \$opts && !exists \$opts) || (exists \$opts &&
!exists \$opts);

But I can't find one!  Several other attempts are just as wordy and have
more tortured logic.  Suggestions?

--

Henry Law            Manchester, England

## Re: Neat way of checking that two hash values both exist?

if exists \$opts == exists \$opts

--
Tim McDaniel, tmcd@panix.com

## Re: Neat way of checking that two hash values both exist?

To expand on that,

IF you have Perl boolean values, by which I mean there are only two
possible values, where one evaluates to true and one evaluates to
false (and I believe that exists fulfils that),

THEN != is the exclusive-or function: it is true if an only if exactly
one of its operands is true.

And therefore == is the inverse: true if and only if both operands are
true or both operands are false.

You may not have such a boolean.  For example, you might have a
function returning a number, and you want to just check that both are
zero or both are non-zero.  You can't do
somefunc(\$x) == somefunc(\$y)
because maybe that's (for example)
12 == 27
which is incorrect.

So !! is Perl's "convert to boolean" operator:
!!(something that evaluates to false) -> ''
!!(something that evaluates to true) -> 1

So the more general way to do exclusive or for values that are simply
either Perl true or Perl false, but might be any true or false value,
!!val1 != !!val2
and so the general "both or neither" is
!!val1 == !!val2

--
Tim McDaniel, tmcd@panix.com

## Re: Neat way of checking that two hash values both exist?

On 27/08/12 17:44, Tim McDaniel wrote:

This is wonderful.  So helpful, and exactly what I wanted by way of
ingenuity.  I've been coding in Perl for several years now (strictly as
an amateur, though) but I've still got a great deal to learn.

As you say 'exists' returns only true or false so I can use the shorter
method.

--

Henry Law            Manchester, England

## Re: Neat way of checking that two hash values both exist?

Quoth tmcd@panix.com:

It does.

<snip>

It's worth being clear that !! is not an operator in its own right, but
simply two instances of !. I'm sure you know this, but I have seen
people confused about it in the past.

Or, you know, use exclusive or? For some reason I have never been able
to work out there is no ^^ operator, so you have to use 'xor':

if (\$val1 xor \$val2)
unless (\$val1 xor \$val2)

Don't make the mistake of using ^ for logical tests; the only case where
it works reliably is when your values are already 1 or 0, in which case
== and != are clearer.

!! is worth knowing about as a concept, though, despite being so ugly.

Ben

## Re: Neat way of checking that two hash values both exist?

which was silly.  Sorry.  For != as exclusive or and similar ==, you
just need two distinct values that can be compared numerically.  A
true number and 0 fulfil the condition, but 17 and 42 would work too.
I was just trying to express that you can't have more than two
values.

Quite so.  Sorry for being confusing.

I tend not to remember "and", "or", and "xor" because they came in
well after I started Perling, and there is no ^^.  Of course, you need
to remember that "and", "or", and "xor" have very low precedence, so
while you don't need parens in
\$both = \$a && \$b;
\$either = !!\$a == !!\$b
you do need parens in
\$both = (\$a and \$b);
\$either = (\$a xor \$b);

--
Tim McDaniel, tmcd@panix.com

## Re: Neat way of checking that two hash values both exist?

In our last episode, the evil Dr. Lacto had captured our hero,

I know this is outside the scope of your question ... but if the
flags must either both be specified or both be unspecified, then why
do you have two flags?

--hymie!    http://lactose.homelinux.net/~hymie hymie@lactose.homelinux.net
-------------------------------------------------------------------------------

## Re: Neat way of checking that two hash values both exist?

The option parsing modules that I know of allow no more than one
string value argument for a single option.  If you need two option
values for a given purpose and you're using such a module, then you
have to accomodate it.

(I can imagine being pedantic and wanting to make something clear to
the user that option 1 implies option 2 by requiring them to enter
both options, but I don't know of any commands that do that.)

--
Tim McDaniel, tmcd@panix.com

## Re: Neat way of checking that two hash values both exist?

On 27/08/12 19:50, hymie! wrote:

It's a good question; or at least it would be if I hadn't complicated
matters by simplifying the example.  They're not just flags: they have
values too.  -p foo -h bar.

I suppose I could have combined the two values, -x "foo@bar" or some
such, but then I'd have had to parse the two halves out again and check
that they were both there.

--

Henry Law            Manchester, England