Hi! Please consider following me on twitter: @hanekomu.
2010年03月18日
Boolean normalization using the logical negation operator
The perlsyn manpage says the following about truth and
falsehood:
The number 0, the strings '0' and '', the empty list "()", and "undef" are all false in a boolean context. All other values are true. Negation of a true value by "!" or "not" returns a special false value. When evaluated as a string it is treated as '', but as a number, it is treated as 0.
Sometimes you want to normalize a value so that it is 1 if it is a true value and 0 if it is a false value. This is sometimes called boolean normalization.
Usually you will see something like this:
my $b = $value ? 1 : 0;
There is an easier way. You could make use of the logical negation operator,
!. When it is applied to a true value, it returns a dual value
that is the number zero in numerical context and the empty string in string
context. When the logical negation operator is applied to a false value, it
returns a dual value that is the number 1 in numerical context and the string
"1" in string context. Let's see this in detail:
$ perl -MDevel::Peek -le'Dump !42' SV = PVNV(0x802000) at 0x12fef8 REFCNT = 2147483647 FLAGS = (IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x200160 ""\0 CUR = 0 LEN = 4 $ perl -MDevel::Peek -le'Dump !0' SV = PVNV(0x802014) at 0x12ff08 REFCNT = 2147483646 FLAGS = (IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x200170 "1"\0 CUR = 1 LEN = 4
By using the logical negation operator twice you can therefore simplify the above statement to:
my $b = !!$value;
And if you wanted the opposite boolean normalization, it's even easier:
my $b = $value ? 0 : 1;
becomes:
my $b = !$value;
posted at: 08:22 | path: /dev | permalink | 11 comments | 0 trackbacks
2010年03月17日
Use parent.pm instead of base.pm
For years, the common way for your class to inherit from one or more superclasses was the base module. For example:
package Game; sub new { bless {}, shift } package Baduk; use base 'Game';
This works, but some people, me included, aren't quite happy with that. Basically, the above could also be expressed as:
package Game; sub new { bless {}, shift } package Baduk; our @ISA = qw(Game);
If the two packages were in different files, the Baduk package
would have to load the file where the Game package lives in as
well. But that's about it.
However, base.pm goes further than that. It supports deprecated
pseudohases, tries to be clever with $VERSION and generally just
does too much. A lot of cruft has accumulated over the years. So a new module,
parent, was forked from base.pm and cleaned
up.
Using parent.pm is pretty much the same as
base.pm:
package Game; sub new { bless {}, shift } package Baduk; use parent 'Game';
This will try to load Game.pm as well. If the Game
package is in a different file that is already loaded, you can tell
parent.pm not to try to load the file:
package Game; sub new { bless {}, shift } package Baduk; use parent -norequire, 'Game';
Compare the source of the two modules and you will find that
parent.pm is a lot cleaner and easier to understand.
posted at: 23:26 | path: /cpan_gems | permalink | 3 comments | 0 trackbacks