Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Don't understand: when('foo' and/or 'bar')

Reply
Thread Tools

Don't understand: when('foo' and/or 'bar')

 
 
Wolfram Humann
Guest
Posts: n/a
 
      05-18-2010
Would someone be so kind to explain the following (quotes are for
win32 perl):

perl -E" $u='foo'; given($u){ when('foo' and 'bar'){say 'f'}
default{say 'd'} } "
d
perl -E" $u='bar'; given($u){ when('foo' and 'bar'){say 'f'}
default{say 'd'} } "
f
perl -E" $u='baz'; given($u){ when('foo' and 'bar'){say 'f'}
default{say 'd'} } "
d
perl -E" $u='foo'; given($u){ when('foo' or 'bar'){say 'f'}
default{say 'd'} } "
f
perl -E" $u='bar'; given($u){ when('foo' or 'bar'){say 'f'}
default{say 'd'} } "
d
perl -E" $u='baz'; given($u){ when('foo' or 'bar'){say 'f'}
default{say 'd'} } "
d

My expectation was: smart matching of two strings uses 'eq'. $u can
not be equal to both 'foo' and 'bar' at the same time so in the 'and'
case I always expect the default 'd'. In the 'or' case I expect 'f' to
be printed if $u is either 'foo' or 'bar'.
Why is my expectation wrong?
 
Reply With Quote
 
 
 
 
Willem
Guest
Posts: n/a
 
      05-18-2010
Wolfram Humann wrote:
) Would someone be so kind to explain the following (quotes are for
) win32 perl):
)
) perl -E" $u='foo'; given($u){ when('foo' and 'bar'){say 'f'}
) default{say 'd'} } "
) d
) perl -E" $u='bar'; given($u){ when('foo' and 'bar'){say 'f'}
) default{say 'd'} } "
) f
) perl -E" $u='baz'; given($u){ when('foo' and 'bar'){say 'f'}
) default{say 'd'} } "
) d
) perl -E" $u='foo'; given($u){ when('foo' or 'bar'){say 'f'}
) default{say 'd'} } "
) f
) perl -E" $u='bar'; given($u){ when('foo' or 'bar'){say 'f'}
) default{say 'd'} } "
) d
) perl -E" $u='baz'; given($u){ when('foo' or 'bar'){say 'f'}
) default{say 'd'} } "
) d
) My expectation was: smart matching of two strings uses 'eq'. $u can
) not be equal to both 'foo' and 'bar' at the same time so in the 'and'
) case I always expect the default 'd'. In the 'or' case I expect 'f' to
) be printed if $u is either 'foo' or 'bar'.
) Why is my expectation wrong?

print('foo' and 'bar'); # bar
print('foo' or 'bar'); # foo

I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
 
 
 
Wolfram Humann
Guest
Posts: n/a
 
      05-18-2010
On 18 Mai, 18:54, Willem <(E-Mail Removed)> wrote:
> print('foo' and 'bar'); *# bar
> print('foo' or 'bar'); * # foo
>
> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.
>


Hm, sounds reasonable. However, it's not really what I expected from
the explanation for "when(EXPR)" in perlsyn:
Furthermore:
If EXPR is ... && ... or ... and ..., the test is applied
recursively to both arguments. If both arguments pass the test, then
the argument is treated as boolean.
If EXPR is ... || ... or ... or ..., the test is applied
recursively to the first argument.
These rules look complicated, but usually they will do what you
want.

As a matter of fact, if the 'and' and 'or' are evaluated before the
smart matching applies, IMHO it would be better to state exactly that
instead of saying "usually they will do what you want"
Thanks for the reply,
Wolfram


 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      05-18-2010
>>>>> "WH" == Wolfram Humann <(E-Mail Removed)> writes:

WH> On 18 Mai, 18:54, Willem <(E-Mail Removed)> wrote:
>> print('foo' and 'bar'); *# bar
>> print('foo' or 'bar'); * # foo
>>
>> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.
>>


WH> Hm, sounds reasonable. However, it's not really what I expected from
WH> the explanation for "when(EXPR)" in perlsyn:
WH> Furthermore:
WH> If EXPR is ... && ... or ... and ..., the test is applied
WH> recursively to both arguments. If both arguments pass the test, then
WH> the argument is treated as boolean.
WH> If EXPR is ... || ... or ... or ..., the test is applied
WH> recursively to the first argument.
WH> These rules look complicated, but usually they will do what you
WH> want.

having read the docs i agree it isn't very clear. try it again with
regexes like /foo/ and /bar/ also with && instead of 'and'. i feel the
logic as the docs seem to say is $_ ~~ EXPR which makes it:

$_ ~~ 'foo' and 'bar'
that evaluates to
($_ ~~ 'foo') and 'bar'

so it won't distribute as you think (and the docs seem to imply). this
could be a bug in perl or the docs. i would raise the issue on p5p as
this definitely seems ambiguous.

also try explicit tests like $_ eq 'foo' which should work.

uri

--
Uri Guttman ------ http://www.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      05-18-2010
On Tue, 18 May 2010 11:06:34 -0700 (PDT), Wolfram Humann <(E-Mail Removed)> wrote:

>On 18 Mai, 18:54, Willem <(E-Mail Removed)> wrote:
>> print('foo' and 'bar'); *# bar
>> print('foo' or 'bar'); * # foo
>>
>> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.
>>

>
>Hm, sounds reasonable. However, it's not really what I expected from
>the explanation for "when(EXPR)" in perlsyn:
> Furthermore:
> If EXPR is ... && ... or ... and ..., the test is applied
>recursively to both arguments. If both arguments pass the test, then
>the argument is treated as boolean.
> If EXPR is ... || ... or ... or ..., the test is applied
>recursively to the first argument.
> These rules look complicated, but usually they will do what you
>want.
>
>As a matter of fact, if the 'and' and 'or' are evaluated before the
>smart matching applies, IMHO it would be better to state exactly that
>instead of saying "usually they will do what you want"
>Thanks for the reply,
>Wolfram
>


Hum, hows that old given/when thing worky for ya?
Recursive boolean expression, now where has that been all these years?

-sln
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      05-18-2010
Wolfram Humann wrote:
) On 18 Mai, 18:54, Willem <(E-Mail Removed)> wrote:
)> print('foo' and 'bar'); ?# bar
)> print('foo' or 'bar'); ? # foo
)>
)> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.
)>
)
) Hm, sounds reasonable. However, it's not really what I expected from
) the explanation for "when(EXPR)" in perlsyn:
) Furthermore:
) If EXPR is ... && ... or ... and ..., the test is applied
) recursively to both arguments. If both arguments pass the test, then
) the argument is treated as boolean.
) If EXPR is ... || ... or ... or ..., the test is applied
) recursively to the first argument.
) These rules look complicated, but usually they will do what you
) want.

Perhaps you should read back and see what 'the test' is that they are
talking about (it's the test to see if smart matching applies or not).

In your case, the test doesn't apply, and smart matching is done.
Then you get ($_ ~~ ('foo' or 'bar')), which evaluates to ($_ ~~ 'foo')

) As a matter of fact, if the 'and' and 'or' are evaluated before the
) smart matching applies, IMHO it would be better to state exactly that
) instead of saying "usually they will do what you want"

The bit you quoted doesn't have to do with that, it's just about deciding
when to apply smart matching or not. I guess a perl guru can give a more
detailed explanation on that.

Smart matching itself doesn't do anything special with &&, and, ||, or.
('bar' ~~ ('foo' or 'bar')) evaluates to 0.

However, to get the behaviour for 'or' that you want, you can do something
like: given($x) { when (['foo', 'bar']) { say 'f' } }


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      05-18-2010
On May 18, 9:54*am, Willem <(E-Mail Removed)> wrote:
> Wolfram Humann wrote:
>
> ) Would someone be so kind to explain the following (quotes are for
> ) win32 perl):
> )
> ) perl -E" $u='foo'; given($u){ when('foo' and 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) d
> ) perl -E" $u='bar'; given($u){ when('foo' and 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) f
> ) perl -E" $u='baz'; given($u){ when('foo' and 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) d
> ) perl -E" $u='foo'; given($u){ when('foo' or 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) f
> ) perl -E" $u='bar'; given($u){ when('foo' or 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) d
> ) perl -E" $u='baz'; given($u){ when('foo' or 'bar'){say 'f'}
> ) default{say 'd'} } "
> ) d
> ) My expectation was: smart matching of two strings uses 'eq'. $u can
> ) not be equal to both 'foo' and 'bar' at the same time so in the 'and'
> ) case I always expect the default 'd'. In the 'or' case I expect 'f' to
> ) be printed if $u is either 'foo' or 'bar'.
> ) Why is my expectation wrong?
>
> print('foo' and 'bar'); *# bar
> print('foo' or 'bar'); * # foo
>
> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.
>


That seems to be the case:

perl -MO=Deparse -E"$u='foo'; given($u){ when('foo' and 'bar'){say
'f'}
default{say 'd'} } "
BEGIN { ... }
$u = 'foo';
given ($u) {
when ('bar') {
say 'f';
}
default {
say 'd';
}
}

perl -MO=Deparse -E" $u='bar'; given($u){ when('foo' or 'bar'){
say 'f'} default{ say 'd'} } "
BEGIN { ... }
$u = 'bar';
given ($u) {
when ('foo') {
say 'f';
}
default {
say 'd';
}
}


--
Charles DeRykus
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      05-18-2010
>>>>> "CD" == C DeRykus <(E-Mail Removed)> writes:

>> I guess the smart matching doesn't distribute ofer the 'and' or the 'or'.


CD> That seems to be the case:

CD> perl -MO=Deparse -E"$u='foo'; given($u){ when('foo' and 'bar'){say
CD> 'f'}
CD> default{say 'd'} } "
CD> BEGIN { ... }
CD> $u = 'foo';
CD> given ($u) {
CD> when ('bar') {

'foo' and 'bar' compile time reduce to 'bar'.


CD> say 'f';
CD> }
CD> default {
CD> say 'd';
CD> }
CD> }

CD> perl -MO=Deparse -E" $u='bar'; given($u){ when('foo' or 'bar'){
CD> say 'f'} default{ say 'd'} } "
CD> BEGIN { ... }
CD> $u = 'bar';
CD> given ($u) {
CD> when ('foo') {

'foo' or 'bar' compile time reduce to 'foo'.


CD> say 'f';
CD> }
CD> default {
CD> say 'd';
CD> }
CD> }

given (pun intended) that, i would say the docs are buggy in this
area. or at least ambiguous and should be fixed. the 'test' for type
inside the when seems to be for simple types and not complex
expressions. this makes some sense in that how would perl know which
smart match mode to use for each part of a complex boolean expression?
but the docs should explain that better as it does

In fact "when(EXPR)" is treated as an implicit smart match most
of the time. The exceptions are that when EXPR is:

so it isn't all the time that is does a smart match.

o If EXPR is "... && ..." or "... and ...", the test is applied
recursively to both arguments. If both arguments pass the test,
then the argument is treated as boolean.

that is poorly written IMO. it seems to mean (as we have learned) the
test for the TYPE is done on both boolean args. then this expression is
run just as a boolean (and that is why the deparse drops the second
boolean arg - it can't affect the boolean since the other arg is a
constant). but how would you ever implicitly invoke smart matching if
you have a boolean expression? the example in the docs shows:

when (/^\d+$/ && $_ < 75) { ... }

and that does not imply any smart matching. it is a regex against $_ and
a normal expression.

this does need some more explanation. i see a smart match tutorial in
the future (prolly not from me!).

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      05-18-2010
On 2010-05-18, Uri Guttman <(E-Mail Removed)> wrote:
> constant). but how would you ever implicitly invoke smart matching if
> you have a boolean expression? the example in the docs shows:
>
> when (/^\d+$/ && $_ < 75) { ... }
>
> and that does not imply any smart matching. it is a regex against $_ and
> a normal expression.
>
> this does need some more explanation. i see a smart match tutorial in
> the future (prolly not from me!).


I think the much more productive solution is to avoid smart matching
completely. (I have no idea WHY it was added to the language; looks
like a severely not-enough-thought-about feature...)

Yours,
Ilya
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      05-19-2010
>>>>> "IZ" == Ilya Zakharevich <(E-Mail Removed)> writes:

IZ> On 2010-05-18, Uri Guttman <(E-Mail Removed)> wrote:
>> constant). but how would you ever implicitly invoke smart matching if
>> you have a boolean expression? the example in the docs shows:
>>
>> when (/^\d+$/ && $_ < 75) { ... }
>>
>> and that does not imply any smart matching. it is a regex against $_ and
>> a normal expression.
>>
>> this does need some more explanation. i see a smart match tutorial in
>> the future (prolly not from me!).


IZ> I think the much more productive solution is to avoid smart matching
IZ> completely. (I have no idea WHY it was added to the language; looks
IZ> like a severely not-enough-thought-about feature...)

this isn't a smart matching issue but a when/given issue and when it
will use smart matching. if you want to bitch about a feature, then
know which is which before you bitch!

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments