On Sep 2, 2012, at 4:28 PM, Ricardo Signes wrote: > * Father Chrysostomos <sprout@cpan.org> [2012-09-02T19:06:43] >>> It seems likely. After all, when already only *usually* means smartmatch. >>> For example, when($x ~~ $y) is boolean, not "$_ ~~ ($x ~~ y)". when($x && >>> $y) means "$_~~$x && $_~~$y" >> >> No, actually it means $_ ~~ ($x && $y), making it more useless than ever. >> >> It means, Match against $x if it is true; match against $y otherwise. > > A reading from perlsyn: >> Furthermore, Perl inspects the operands of logical operators to decide >> whether to use smartmatching for each one by applying the above test to >> the operands: >> >> 9. If EXPR is "EXPR1 && EXPR2" or "EXPR1 and EXPR2", the test is >> applied recursively to both EXPR1 and EXPR2. Only if both operands >> also pass the test, recursively, will the expression be treated as >> boolean. Otherwise, smartmatching is used. ‘Is used’ doesn’t say to which expression or expressions smartmatch is applied. Yes, I originally thought when($a && $b) meant when ($_ ~~ $a && $_ ~~ $b), but when looking into making it deparse properly I found that not to be the case. > > And a program to demonstrate it: > > use 5.16.1; > > package SM { > use overload 'bool' => sub { return }, > '~~' => sub { 1 }; > } > > my $sm = bless {}, 'SM'; > > say($sm ? 'sm is true' : 'sm is false'); > > given ($sm) { > when ($sm && $sm) { say 'when was entered' } > } > > Am I missing something, or are you? In that example, we effectively have: $sm ~~ ($sm && $sm) The boolean falsity causes the $sm on the rhs of && to be used, which returns true for ~~. It makes no difference if you use the same thing on both sides of &&. Look at this one-liner: $ perl -lE '$o=1; $z=0; given(0) { when($o && $z) { print "matched" } };' matched Surely 0~~1 and 0~~0 can’t both be true at the same time. > Back to Sprout: >> [ ... ] >> What about objects that are not overloaded? What about qr//, which returns >> an object? > > qr// objects are made ot behave like =~ qr//. > > Objects that are not overloaded remain fatal. > >> If we respect qr and &{} overloading, or if non-overloaded objects just >> croak, I still maintain that this is going to cause problems for module >> authors that want to add extra functionality to existing objects without >> breaking code that uses the modules. > > Way back when, around 5.10.x, I argued that we should require ~~ overloading > for ~~, not fall back to anything else. I think I was right then and merely > forgot about it until recently. > >> Maybe the only reasonable chart would be this: >> >> 1. !defined($rhs) >> 2. overload::Method($rhs, "~~"); >> 3. reftype($rhs) eq 'CODE' >> 4. reftype($rhs) eq 'REGEXP' >> 5. ? > > Right. It avoids (a) ambiguity (b) breaking code when you /had/ &{} but /add/ > qr and /not/ ~~. This was the concern then, too, but with regard to %{} and > @{} and object guts. And allows for blessed CODE thingies that are blessed solely to provide extra methods. And allows reblessed Regexps to continue working. > >> Should 5 be a deprecation warning? Or just a croak? > > I'd just make it fail. It's like saying "push $hashref" ;) (You haven’t forgotten, have you, that I’d like to made that equivalent to push %$hashref?) >>> Under FC's proposal, which would eliminate ~~ entirely: >>> >>> given ($input) { >>> when (1) { ... } # if $input == 1 >>> when ('x') { ... } # if $input eq 'x' >>> when ($x) { ... } # if $x >>> when (undef) { ... } # if undef >> >> Of course, one would write when (!defined). > > Of course! Think-o. :) > >>> when ($x + 2) { ... } # if ($x+2) >>> when ($_ > 1) { ... } # if ($_ > 1) >>> } >> >> We already have many operators that imply $_. Maybe what we really ought to >> be doing is extending that. If we can come up with new ways to imply $_ in >> arbitrary expressions, then if() would benefit, too. > > Any suggestions? No, not yet. :-) I thought by mentioning that I could get people to help brainstorm. For qr// and undef we already have /$qr/ and !defined. For sub calls? ... > >> And, since you have not answered it yet, should given respond to next? > > Almost certainly. Was there ever any given (ha ha) reason not to? Is it fear > of changing the behavior of existing givens inside loops? I think Zefram raised exactly that objection a year ago. >> And here is another aspect of when/default that makes the way it breaks >> special: >> >> for (3) { >> for my $x (4) { >> when (3) {} >> } >> warn "exited inner"; >> } >> warn "exited outer"; >> >> That prints "exited outer at - line 7". So when doesn’t just do ‘next’ >> inside for. >> >> I think that should change. > > Well, the issue is that when interacts with a topicalizer. Except for when{}{}. :-) But I hope we don’t make when{}{} and when(){} break differently. > It is going to do > its work based on the topicalization that has occurred, and so having its > implicit break behave like a 'next' on the relevant topicalizer is not > obviously nuts. A sub called from within for(...){...} could do local $_, while(<>) { .... }. Currently that will exit the caller’s loop.Thread Previous | Thread Next