[sf-perl] Re: [oak perl] print Dumper \$|;
Belden Lyman
blyman at iii.com
Thu Jan 16 11:20:18 CST 2003
qw at sf.pm.org wrote:
> Oops, I forgot to CC Oakland.pm. Please reply-all to this message,
> not the previous one, to include them.
Let's blame the OP for being a cross-posting lame-o.
Oh, wait, that's me. Well, still. :)
>
> That's confusing. I first thought maybe $| was a tied variable, which
> would explain this behavior. So, I tried doing 'tied $|' to see what
> it was tied to. The result was undef--meaning it's not a tied. But,
> wait, 'tied %ENV' also returns undef. Does anyone know why? Is this
> a bug? (All of this is in Perl 5.6.1 on Solaris.)
>
I think $| manages to achieve its boolean magic without using tie.
But this is just a guess based on your test.
> Anyway, I guess the larger moral of this story is that $| has a
> Boolean value, and you should only think of it in terms of true
> (nonzero) or false (zero), and not do math operations on it. Why
> would you want to increment $|, anyway?
>
$| = 1; # autoflush pipes
$|++; # same as $| = 1;
$| = 0; # umm, clog pipes
$|--; # same as $| = 0;
What's neat is that you can $|++ all you want, but the highest value
that $| will ever have is 1; similarly, you can $|-- all you want,
but it'll always be ...
And it's the ... that I was trying to get Data::Dumper to tell me:
I expected to see either 0 or undef as the value for $|--, but instead
saw 1.
The reason I even care about this is that I like having the option to
toggle $| either by setting it directly or by (in|de)crementing it.
More to the point, I like this option so much that yesterday I wrote
up Tie::Boolean that allows one to stuff like this:
package Person;
use Tie::Boolean;
sub new {
my (
$invocant,
%args,
) = @_;
my $class = ref $invocant || $invocant;
my $self = \%args;
tie $self->{effusive}, q/Tie::Boolean/, 0;
bless $self, $class;
$self->effusive++ if $self->{job} =~ /sales/i;
return $self;
}
sub effusive : lvalue { # lvalue is experimental
my $self = shift;
$self->{effusive}; # don't use return
}
sub introduce {
my $self = shift;
if ( $self->effusive ) {
print "Salutations! Greetings! Avast, matey!\n";
}
print "My name is ", $self->{name},
" and I am a ", $self->{job},
"\n";
}
package main;
my $resident = Person->new( name => 'Betty Rubble',
job => 'Comptroller', );
my $salesman = Person->new( name => 'Fred Flintstone',
job => 'Encyclopedia Salesman' );
$salesman->introduce(); # he's in sales, he's effusive
$resident->introduce(); # she's not in sales, not effusive
$salesman->effusive--; # make him more guarded
$resident->effusive++; # make her more effusive
$salesman->introduce(); # they meet again!
$resident->introduce();
exit;
See, being able to do:
$resident->effusive++;
gives me two things:
1. It saves me a whopping 1 keystroke:
$resident->effusive(1); # old, set explicitly
$resident->effusive++; # new
(Of course, either of these invocations would work.)
2. But I'm really not much of a golfer, so I actually don't care
about shaving off 1 keystroke. The big gain for me is that
effusive() doesn't have to care what data it's being handed.
Internally, Tie::Boolean represents true as (surprise) 1 and false
as (surprise again) 0. At the end of the day yesterday I had a crisis
of correctness: should false be zero, or undef, or an empty string?
So I tried asking Data::Dumper the value of --$|, and got right
confused when Dumper thought --$| was the same as ++$|.
Oh, in the end, I decided to use 0 for false: the module is
called Tie::Boolean, not Tie::Defined.
Thanks to anyone who read this far.
Belden
More information about the Oakland
mailing list