develooper Front page | perl.perl5.porters | Postings from December 2001

can and tied variables

Thread Next
From:
Tels
Date:
December 22, 2001 07:54
Subject:
can and tied variables
Message ID:
perl.perl5.porters-49823@nntp.perl.org
-----BEGIN PGP SIGNED MESSAGE-----

Moin,

I am tracking down a nasty bug in Math::BigInt and it resolves to a problem
with tie() and can(). Since I am neither a Perl nor a tie() expert, I would
like to ask someone to have a look and tell me if this is a bug of mine, or
in the way tie() works:

T.pm:

package T;

require Exporter;
@ISA = qw(Exporter);

sub foo
  {
  1;
  }

1;

tt.pl:
#!/usr/bin/perl -w

use strict;
use Test;
BEGIN { plan  tests => 9; }

my $T = '';
my $A = 'T';

sub STORE      { print "STORE\n"; $A = $_[1]; }
sub FETCH      { print "FETCH\n"; $A; }
sub TIESCALAR  { my ($class,$var) = @_; bless \$var, $class; }

use T;

ok ($A->can('foo') =~ /^CODE/,1);
ok (T->can('foo') =~ /^CODE/,1);                # this always works

print "# tie\n";
tie $T, 'main';
ok ($T->can('foo') =~ /^CODE/,1);
ok ($T,'T');

print "# store\n";
$T = 'T';

print "# after\n";
ok ($T->can('foo') =~ /^CODE/,1);
ok ($T,'T');

print "# untie\n";
untie $T;

ok ($T->can('foo') =~ /^CODE/,1);

$T = 'T';

ok ($T->can('foo') =~ /^CODE/,1);
ok ($A->can('foo') =~ /^CODE/,1);

When run:

te@null:~/perl/math > perl tt.pl
1..9
ok 1
ok 2
# tie
FETCH
FETCH
FETCH
Use of uninitialized value in pattern match (m//) at tt.pl line 21.
not ok 3
# Test 3 got: '' (tt.pl at line 21)
#   Expected: '1'
FETCH
ok 4
# store
STORE
# after
FETCH
FETCH
FETCH
Use of uninitialized value in pattern match (m//) at tt.pl line 28.
not ok 5
# Test 5 got: '' (tt.pl at line 28)
#   Expected: '1'
FETCH
ok 6
# untie
ok 7
ok 8
ok 9


Which looks like a tied() variable can not be used in a $VAR->can() style
:-/ Apart from this, Math::BigInt is untie-ing the variable inside the
FETCH, so the variable should no longer be tied when accessed via can()
anyway. But it seems that even this doesn't work like I expect
(although it works in that testcase). Probably an untie() problem. How can
I find out whether a variable is tied? 

And the three times fetch also makes me wonder...

Here is the tie() section in Math::BigInt, can anybody with some tie()
experience please comment whether this will cause trouble? (I can work
around the can() problem, but I can hardly leave of that tie() section,
since it makes 'require Math::BigInt' work again):

#########################################################################
# make require Math::BigInt; work (upon require, no import is called, but
# upon the first math operation requesting the value of $CALC it will be
# set in the background by import, the actual value returned. In the
# meanwhile, fetch has untied the variable, so that the next access is
# to a plain scalar.

package Math::BigInt::Load::Calc;

sub TIESCALAR  { my ($class) = @_; bless \$CALC, $class; }
sub STORE      { $CALC = $_[1]; }

# if we land in here, an 'require Math::BigInt' without import() was done
sub FETCH
  {
  # print "FETCH ",join(' ',caller()),"\n";
  untie $CALC;
  if ($IMPORT == 0)
    {
    $CALC = 'Math::BigInt::Calc';
    my $lib = $CALC;
    if ($] < 5.006)
      {
      # Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant'
      # is used in the same script, or eval inside import().
      (my $mod = $lib . '.pm') =~ s!::!/!g;
      #print "eval { require $mod; }\n";
      # require does not automatically :: => /, so portability problems
      # arise
      eval { require $mod; }
      }
    else
      {
      #print "eval 'use $lib;\n";
      eval "use $lib;";
      }
    }
  $CALC;
  }

package Math::BigInt;

BEGIN { tie $CALC, 'Math::BigInt::Load::Calc'; }

#######################################################################
 

Thank you in advance,

Tels

- -- 
perl -MMath::String -e 'print \
Math::String->from_number("215960156869840440586892398248"),"\n"'

 http://bloodgate.com/perl       My current Perl projects
 PGP key available on http://bloodgate.com/tels.asc or via email.


-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i
Charset: latin1

iQEVAwUBPCSrqXcLPEOTuEwVAQGnPwf7Bfsepf8L21qusGqN9T/3espsvlTJf2w7
mtORHf5BOlskTkzy/Fm2g8iqVYYyZVBQJs1L5IYBuBkQKU/9q81CVE0oyHW8QrBm
3H2KwBTbglEoSdI+j6pQ4ZpatEQn5ME80Z26Q0fAeUbZeA/Ttj0hP4ZfXfJ9w1Sv
iWPEyYibphdNijSJRDDuFnt4wbSZeaPMxz1POgrSJ5Hm2qaSBgUofpaPTyNzM7iX
FuhMrk5kkM6bEsbJD+n63j4UzbHAuOHzBD1gv5aXXbCcdD1QjyoOh07JYBFSmCZz
hzpMjvTFaH+7Yd/U7zSGkxeBgVyKGDKYyJTQaIeDvQUzqnpnaBPUbA==
=U7aZ
-----END PGP SIGNATURE-----

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About