Re: Bit testing
On Nov 14, 1:11 am, shlo...@iglu.org.il (Shlomi Fish) wrote: > Hi Charles, > > On Sunday 14 November 2010 01:47:36 C.DeRykus wrote: > > > On Nov 11, 11:27 pm, c...@pobox.com (Chap Harrison) wrote: > > Not lots shorter but you could use a closure to hide > > the calculation: > > > my $mask; > > for my $flags ( ... ) { > > $mask = sub { return ($flags & $_[0]) == $_[0] } > > unless $mask; > > given( $flags ) { > > when ( $mask->($one_and_three) ) { ... } > > when ( $mask->($zero_and_four) ) { ... } > > ... > > } > > } > > This won't work properly because the closure traps the initial value of > "$flags". For example: > > [code] > #!/usr/bin/perl > > use strict; > use warnings; > > my $closure; > > foreach my $name (qw(Sophie Jack Charles Dan Rachel)) > { > $closure = sub { print "Hello $name!\n" ; } unless $closure; > > $closure->();} > > [/code] > > This prints "Hello Sophie!" five times. Either redeclare the closure on every > iteration, or declare it once while using a more outer lexical variable. Right... or simply get rid of the statement qualifier 'unless $closure' which'll work too and is what you'll have to do in any case. (technically, you could declare 'my $closure' both in/outside the loop leaving the statement qualifier as is but that's horrible ) You could just 'my $closure' solely inside the loop too. Declaring once outside the loop with an outer lexical seems less satisfactory since it loosens the 'tightest lexical scope' best practice. -- Charles DeRykus -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Bit testing
On Nov 14, 2010, at 4:36 AM, C.DeRykus wrote: > And now it seems a little bit > inelegant to redefine the closure each time through > the loop. > > > for my $flags ( ... ) { > my $mask = sub { return ($flags & $_[0]) == $_[0] }; > given( $flags ) { > when ( $mask->($one_and_three) ) { ... } > when ( $mask->($zero_and_four) ) { ... } > ... > } > ... First, thanks for (($flags & $mask) == $mask). What I eventually did was just call a subroutine on($flags, $mask) to do the calculation and determine whether all the specified bits were on. Seems simpler than the closure technique, even if having to repeatedly write '$flags' is less than ideal. However, now I'm determined to get an understanding of closures, and I see another thread on this list that provides several links to help in that regard. Thanks, one and all! Regards, Chap -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Bit testing
On Nov 13, 3:47 pm, dery...@gmail.com ("C.DeRykus") wrote: > On Nov 11, 11:27 pm, c...@pobox.com (Chap Harrison) wrote: > > > > > I'm almost embarrassed to ask this, but I can't figure out a simple way to > > construct a switch ('given') statement where the 'when' clauses involve > > bit-testing. > > > Here's the only way I've figured out to build a switch statement that does > > the trick. It seems unusually wordy, which makes me think there must be a > > simpler way to test for certain bit combinations. Any suggestions? > > > Thanks, > > Chap > > > #!/usr/bin/perl > > > > > > > use strict; > > use warnings; > > use feature ":5.10"; > > > # Here are masks for various bit combos of interest: > > > > > > > my $one_three = 0b1010; # bits 1 and 3 (counting from 0, right > > to left) > > > > my $zero_four = 0b00010001; # bits 0 and 4 > > > > > > my $five = 0b0010; # bit 5 > > > > > > > # Here we will test several bit fields for bit combos of interest: > > > > > > > for my $flags ( 0b10111010, 0b10111000, 0b10010010) { > > > my $asbits = sprintf("0b%08b", $flags); # prepare bits for > > pretty-printing > > > > > given ( $flags ) { > > when ( ($_ & $one_three) == $one_three ) { # bits one and three > > are on > > > > say "$asbits has bits 1 and 3"; > > } > > when ( ($_ & $zero_four) == $zero_four ) { # bits zero and four are > > on > > > > say "$asbits has bits 0 and 4"; > > } > > when ( ($_ & $five) == $five ) { # bit five is on > > > > > > say "$asbits has bit 5"; > > } > > default { > > say "$asbits has no interesting bit patterns."; > > } > > } > > > } > > Not lots shorter but you could use a closure to hide > the calculation: > > my $mask; > for my $flags ( ... ) { > $mask = sub { return ($flags & $_[0]) == $_[0] } > unless $mask; > given( $flags ) { > when ( $mask->($one_and_three) ) { ... } > when ( $mask->($zero_and_four) ) { ... } > ... > } > > } Oops, right. The closure could've/should've been declared w/o a statement qualifier. And now it seems a little bit inelegant to redefine the closure each time through the loop. for my $flags ( ... ) { my $mask = sub { return ($flags & $_[0]) == $_[0] }; given( $flags ) { when ( $mask->($one_and_three) ) { ... } when ( $mask->($zero_and_four) ) { ... } ... } ... -- Charles DeRykus
Re: Bit testing
Hi Charles, On Sunday 14 November 2010 01:47:36 C.DeRykus wrote: > On Nov 11, 11:27 pm, c...@pobox.com (Chap Harrison) wrote: > Not lots shorter but you could use a closure to hide > the calculation: > > my $mask; > for my $flags ( ... ) { > $mask = sub { return ($flags & $_[0]) == $_[0] } > unless $mask; > given( $flags ) { > when ( $mask->($one_and_three) ) { ... } > when ( $mask->($zero_and_four) ) { ... } > ... > } > } > This won't work properly because the closure traps the initial value of "$flags". For example: [code] #!/usr/bin/perl use strict; use warnings; my $closure; foreach my $name (qw(Sophie Jack Charles Dan Rachel)) { $closure = sub { print "Hello $name!\n" ; } unless $closure; $closure->(); } [/code] This prints "Hello Sophie!" five times. Either redeclare the closure on every iteration, or declare it once while using a more outer lexical variable. Regards, Shlomi Fish > -- > Charles DeRykus -- - Shlomi Fish http://www.shlomifish.org/ List of Portability Libraries - http://shlom.in/port-libs She's a hot chick. But she smokes. She can smoke as long as she's smokin'. Please reply to list if it's a mailing list post - http://shlom.in/reply . -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Bit testing
On Nov 11, 11:27 pm, c...@pobox.com (Chap Harrison) wrote: > I'm almost embarrassed to ask this, but I can't figure out a simple way to > construct a switch ('given') statement where the 'when' clauses involve > bit-testing. > > Here's the only way I've figured out to build a switch statement that does > the trick. It seems unusually wordy, which makes me think there must be a > simpler way to test for certain bit combinations. Any suggestions? > > Thanks, > Chap > > #!/usr/bin/perl > > > > use strict; > use warnings; > use feature ":5.10"; > > # Here are masks for various bit combos of interest: > > > > my $one_three = 0b1010; # bits 1 and 3 (counting from 0, right to > left) > > my $zero_four = 0b00010001; # bits 0 and 4 > > > my $five = 0b0010; # bit 5 > > > > # Here we will test several bit fields for bit combos of interest: > > > > for my $flags ( 0b10111010, 0b10111000, 0b10010010) { > > my $asbits = sprintf("0b%08b", $flags); # prepare bits for > pretty-printing > > > given ( $flags ) { > when ( ($_ & $one_three) == $one_three ) { # bits one and three are > on > > say "$asbits has bits 1 and 3"; > } > when ( ($_ & $zero_four) == $zero_four ) { # bits zero and four are > on > > say "$asbits has bits 0 and 4"; > } > when ( ($_ & $five) == $five ) { # bit five is on > > > say "$asbits has bit 5"; > } > default { > say "$asbits has no interesting bit patterns."; > } > } > > } Not lots shorter but you could use a closure to hide the calculation: my $mask; for my $flags ( ... ) { $mask = sub { return ($flags & $_[0]) == $_[0] } unless $mask; given( $flags ) { when ( $mask->($one_and_three) ) { ... } when ( $mask->($zero_and_four) ) { ... } ... } } -- Charles DeRykus
Re: Bit testing
>>>>> "CH" == Chap Harrison writes: CH> I'm almost embarrassed to ask this, but I can't figure out a CH> simple way to construct a switch ('given') statement where the CH> 'when' clauses involve bit-testing. Here's the only way I've CH> figured out to build a switch statement that does the trick. It CH> seems unusually wordy, which makes me think there must be a CH> simpler way to test for certain bit combinations. Any CH> suggestions? CH> when ( ($_ & $one_three) == $one_three ) { # bits one and CH> three are on don't put comments on the same line as code. it can make it line wrap like above. anyhow, some boolean hacking does the trick. this seems to work. when ( !(~$_ & $one_three) ) you invert the flag bits and then and against the test mask. if that is all 0's (tested with !) then your bits were set. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Bit testing
I'm almost embarrassed to ask this, but I can't figure out a simple way to construct a switch ('given') statement where the 'when' clauses involve bit-testing. Here's the only way I've figured out to build a switch statement that does the trick. It seems unusually wordy, which makes me think there must be a simpler way to test for certain bit combinations. Any suggestions? Thanks, Chap #!/usr/bin/perl use strict; use warnings; use feature ":5.10"; # Here are masks for various bit combos of interest: my $one_three= 0b1010; # bits 1 and 3 (counting from 0, right to left) my $zero_four= 0b00010001; # bits 0 and 4 my $five = 0b0010; # bit 5 # Here we will test several bit fields for bit combos of interest: for my $flags ( 0b10111010, 0b10111000, 0b10010010) { my $asbits = sprintf("0b%08b", $flags); # prepare bits for pretty-printing given ( $flags ) { when ( ($_ & $one_three) == $one_three ) { # bits one and three are on say "$asbits has bits 1 and 3"; } when ( ($_ & $zero_four) == $zero_four ) { # bits zero and four are on say "$asbits has bits 0 and 4"; } when ( ($_ & $five) == $five ) { # bit five is on say "$asbits has bit 5"; } default { say "$asbits has no interesting bit patterns."; } } } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/