From: Willem on 18 May 2010 14:35 Wolfram Humann wrote: ) On 18 Mai, 18:54, Willem <wil...(a)turtle.stack.nl> 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
From: C.DeRykus on 18 May 2010 16:29 On May 18, 9:54 am, Willem <wil...(a)turtle.stack.nl> 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
From: Uri Guttman on 18 May 2010 16:44 >>>>> "CD" == C DeRykus <derykus(a)gmail.com> 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 ------ uri(a)stemsystems.com -------- http://www.sysarch.com -- ----- Perl Code Review , Architecture, Development, Training, Support ------ --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
From: Ilya Zakharevich on 18 May 2010 19:19 On 2010-05-18, Uri Guttman <uri(a)StemSystems.com> 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
From: Wolfram Humann on 19 May 2010 06:35 On May 18, 8:25 pm, "Uri Guttman" <u...(a)StemSystems.com> wrote: > 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'. Going from 'and' and 'or' to '&&' and '||' makes no difference. '/foo/ or /bar/' works -- but only because (/foo/ or /bar/) already does what I want without needing any given/when or smartmatching specials. When testing for undef I need to write 'when(/foo/ or !defined($_))'. Maybe Willem's solution below is better here. On May 18, 8:35 pm, Willem <wil...(a)turtle.stack.nl> wrote: > > However, to get the behaviour for 'or' that you want, you can do something > like: given($x) { when (['foo', 'bar']) { say 'f' } } That extends nicely to when(['foo', undef]). Thanks for the idea. The only drawback is that the intention is not as obvious because the 'or' is implicit from the undelying 'grep'-like smartmatching. Thanks for all replies, Wolfram
First
|
Prev
|
Pages: 1 2 Prev: FAQ 4.56 How do I merge two hashes? Next: bit-twiddling on 32-bit machines |