Why does Tie::Simeple (scalar) work without real local data?
Why does Tie::Simeple (scalar) work without real local data?
am 04.12.2006 02:23:18 von paduille.4060.mumia.w
Using Tie::Simple, it's just too easy to create a variable that
increments itself each time it is read:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::Simple;
tie my $incr, 'Tie::Simple', \my $inc,
FETCH => sub { $$_[0]++ },
STORE => sub { $$_[0] = $_[1] };
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
untie $incr;
__END__
I used the syntax "\my $inc" because I wanted the "local data" to be a
reference to a scalar. The above code works as expected. Then I decided
to play with something that should break it:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::Simple;
tie my $incr, 'Tie::Simple', 'Hello',
FETCH => sub { $$_[0]++ },
STORE => sub { $$_[0] = $_[1] };
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
untie $incr;
__END__
Unbelievably, it still works. The "local data," 'hello', is a *constant
string*--not a reference to a scalar. When I put a print statement
inside the FETCH sub to view @_, I see "Hello."
I then discovered that there is nothing I can think of to put in place
of "Hello" that will cause the program to misbehave.
Yes, I checked: "Hello" does not become a variable in ::main accessed
through a symbolic reference. Symbolic references are disabled by "use
strict," and printing the keys to the main hash (%::) doesn't show "Hello."
Usually people are happy when a program works, but I am too darn
curious. Why is it the program won't stop working correctly even if I
replace "'Hello'" with "qr/[a-z]/"?
--
paduille.4060.mumia.w@earthlink.net
Re: Why does Tie::Simeple (scalar) work without real local data?
am 04.12.2006 13:46:02 von rvtol+news
Mumia W. (reading news) schreef:
> FETCH => sub { $$_[0]++ },
FETCH => sub { ${$_[0]}++ },
--
Affijn, Ruud
"Gewoon is een tijger."
Re: Why does Tie::Simeple (scalar) work without real local data?
am 04.12.2006 17:34:36 von paduille.4060.mumia.w
On 12/04/2006 06:46 AM, Dr.Ruud wrote:
> Mumia W. (reading news) schreef:
>
>> FETCH => sub { $$_[0]++ },
>
> FETCH => sub { ${$_[0]}++ },
>
Thank you very much sir. That seems to work to make my program fail when
"'Hello'" is specified as the local data.
Now I see that I was updating $_. Evidently, what I wrote was
interpreted as "FETCH => sub { ${$_}[0]++ }," so I had (accidentally)
turned $_ into an array reference.
If I had been using $_ for anything important, I would've been a very
confused man :-)
Interestingly, even when I put the correct braces in, this weird code
(qr/[a-z]/ as the local data) still works as expected:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::Simple;
tie my $incr, 'Tie::Simple', qr/[a-z]/,
FETCH => sub { ${$_[0]}++ },
STORE => sub { ${$_[0]} = $_[1] };
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
untie $incr;
--
paduille.4060.mumia.w@earthlink.net
Re: Why does Tie::Simeple (scalar) work without real local data?
am 04.12.2006 17:52:29 von rvtol+news
Mumia W. (reading news) schreef:
> On 12/04/2006 06:46 AM, Dr.Ruud wrote:
>> Mumia W. (reading news) schreef:
>>
>>> FETCH => sub { $$_[0]++ },
>>
>> FETCH => sub { ${$_[0]}++ },
>>
>
> Thank you very much sir. That seems to work to make my program fail
> when "'Hello'" is specified as the local data.
>
> Now I see that I was updating $_. Evidently, what I wrote was
> interpreted as "FETCH => sub { ${$_}[0]++ }," so I had (accidentally)
> turned $_ into an array reference.
>
> If I had been using $_ for anything important, I would've been a very
> confused man :-)
>
> Interestingly, even when I put the correct braces in, this weird code
> (qr/[a-z]/ as the local data) still works as expected:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use Tie::Simple;
>
> tie my $incr, 'Tie::Simple', qr/[a-z]/,
> FETCH => sub { ${$_[0]}++ },
> STORE => sub { ${$_[0]} = $_[1] };
>
> print "Right now: $incr\n";
> print "Right now: $incr\n";
> print "Right now: $incr\n";
> print "Right now: $incr\n";
>
> untie $incr;
Before I recognized the problem, I used the source of Tie::Scalar to
convert your source to:
#!/usr/bin/perl -l
use strict ;
use warnings ;
tie my $incr, 'MyTest', -5 ;
print "Right now: $incr" ;
print "Right now: $incr" ;
print "Right now: $incr" ;
print "Right now: $incr" ;
untie $incr ;
package MyTest ;
sub TIESCALAR
{ my $class = shift
; my $instance = shift || undef
; return bless \$instance, $class
}
sub FETCH { ${$_[0]}++ }
sub STORE { $$_[0] = $_[1] }
sub DESTROY { undef ${$_[0]} }
__END__
--
Affijn, Ruud
"Gewoon is een tijger."
Re: Why does Tie::Simeple (scalar) work without real local data?
am 04.12.2006 23:50:41 von paduille.4060.mumia.w
On 12/04/2006 10:52 AM, Dr.Ruud wrote:
> Mumia W. (reading news) schreef:
>> [...]
>> Interestingly, even when I put the correct braces in, this weird code
>> (qr/[a-z]/ as the local data) still works as expected:
>> [... code snipped ...]
>
>
> Before I recognized the problem, I used the source of Tie::Scalar to
> convert your source to:
>
> #!/usr/bin/perl -l
> use strict ;
> use warnings ;
>
> tie my $incr, 'MyTest', -5 ;
>
> print "Right now: $incr" ;
> print "Right now: $incr" ;
> print "Right now: $incr" ;
> print "Right now: $incr" ;
>
> untie $incr ;
>
>
> package MyTest ;
>
> sub TIESCALAR
> { my $class = shift
> ; my $instance = shift || undef
> ; return bless \$instance, $class
> }
>
> sub FETCH { ${$_[0]}++ }
>
> sub STORE { $$_[0] = $_[1] }
>
> sub DESTROY { undef ${$_[0]} }
> __END__
>
Thanks. Now we might be getting somewhere. When I change -5 to
qr/[a-z]/, I get wrong output:
Right now: (?-xism:[a-z])
Right now: 135580925
Right now: 135580926
Right now: 135580927
However, this output still confuses me. It looks like, when a regular
expression variable is incremented, it changes into a number :-O
This code,
#!/usr/local/bin/perl5.9.4
my $sb = qr/[a-z]/;
print "sb before: $sb : type(@{[ ref $sb ]})\n";
$sb++;
print "sb after : $sb : type(@{[ ref $sb ]})\n";
printf "Perl: %vd\n", $^V;
prints this,
sb before: (?-xism:[a-z]) : type(Regexp)
sb after : 135686917 : type()
Perl: 5.9.4
Does anyone know if that is expected or desired behavior? This is not
documented in perlop.
--
paduille.4060.mumia.w@earthlink.net
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 01:03:36 von someone
Mumia W. (reading news) wrote:
>
> Thanks. Now we might be getting somewhere. When I change -5 to
> qr/[a-z]/, I get wrong output:
>
> Right now: (?-xism:[a-z])
> Right now: 135580925
> Right now: 135580926
> Right now: 135580927
>
> However, this output still confuses me. It looks like, when a regular
> expression variable is incremented, it changes into a number :-O
No, when a reference is used as a number it becomes a number:
$ perl -le'$x = {}; print for ref $x, $x, $x + 0'
HASH
HASH(0x816cc20)
135711776
And a qr// object is just a reference after all:
$ perl -le'$x = qr{}; print for ref $x, $x, $x + 0'
Regexp
(?-xism:)
135712052
> This code,
>
> #!/usr/local/bin/perl5.9.4
> my $sb = qr/[a-z]/;
> print "sb before: $sb : type(@{[ ref $sb ]})\n";
> $sb++;
> print "sb after : $sb : type(@{[ ref $sb ]})\n";
> printf "Perl: %vd\n", $^V;
>
> prints this,
>
> sb before: (?-xism:[a-z]) : type(Regexp)
> sb after : 135686917 : type()
> Perl: 5.9.4
>
> Does anyone know if that is expected or desired behavior? This is not
> documented in perlop.
If you increment a reference it *becomes* a number and cannot be changed back
to a reference. Likewise, if you stringify a reference it cannot be changed
back to a reference.
John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 05:32:01 von paduille.4060.mumia.w
On 12/04/2006 06:03 PM, John W. Krahn wrote:
> Mumia W. (reading news) wrote:
>> Thanks. Now we might be getting somewhere. When I change -5 to
>> qr/[a-z]/, I get wrong output:
>>
>> Right now: (?-xism:[a-z])
>> Right now: 135580925
>> Right now: 135580926
>> Right now: 135580927
>>
>> However, this output still confuses me. It looks like, when a regular
>> expression variable is incremented, it changes into a number :-O
>
> No, when a reference is used as a number it becomes a number:
>
> $ perl -le'$x = {}; print for ref $x, $x, $x + 0'
> HASH
> HASH(0x816cc20)
> 135711776
>
> And a qr// object is just a reference after all:
>
> $ perl -le'$x = qr{}; print for ref $x, $x, $x + 0'
> Regexp
> (?-xism:)
> 135712052
>
>
>> This code,
>>
>> #!/usr/local/bin/perl5.9.4
>> my $sb = qr/[a-z]/;
>> print "sb before: $sb : type(@{[ ref $sb ]})\n";
>> $sb++;
>> print "sb after : $sb : type(@{[ ref $sb ]})\n";
>> printf "Perl: %vd\n", $^V;
>>
>> prints this,
>>
>> sb before: (?-xism:[a-z]) : type(Regexp)
>> sb after : 135686917 : type()
>> Perl: 5.9.4
>>
>> Does anyone know if that is expected or desired behavior? This is not
>> documented in perlop.
>
> If you increment a reference it *becomes* a number and cannot be changed back
> to a reference. Likewise, if you stringify a reference it cannot be changed
> back to a reference.
>
>
>
>
> John
Interesting. Perl references can become numbers but can't return to
references again. That's not quite like C :-)
But I still wonder why this program works so well:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::Simple;
my $sb = qr/[a-z]/;
tie my $incr, 'Tie::Simple', $sb,
FETCH => sub { ${$_[0]}++ },
STORE => sub { ${$_[0]} = $_[1] };
print "sb1: $sb\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "Right now: $incr\n";
print "sb2: $sb\n";
untie $incr;
-------------
That program prints this:
sb1: (?-xism:[a-z])
Right now: 0
Right now: 1
Right now: 2
Right now: 3
sb2: Regexp=SCALAR(0x814cc6c)
The regular expression is somehow changed, and it seems to be storing my
value in it, but compiled regular expressions can't contain numbers--can
they?
--
paduille.4060.mumia.w@earthlink.net
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 10:32:11 von someone
Mumia W. (reading news) wrote:
>
> Interesting. Perl references can become numbers but can't return to
> references again. That's not quite like C :-)
>
> But I still wonder why this program works so well:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use Tie::Simple;
>
> my $sb = qr/[a-z]/;
>
> tie my $incr, 'Tie::Simple', $sb,
> FETCH => sub { ${$_[0]}++ },
> STORE => sub { ${$_[0]} = $_[1] };
>
> print "sb1: $sb\n";
> print "Right now: $incr\n";
> print "Right now: $incr\n";
> print "Right now: $incr\n";
> print "Right now: $incr\n";
> print "sb2: $sb\n";
>
> untie $incr;
>
> -------------
> That program prints this:
>
> sb1: (?-xism:[a-z])
> Right now: 0
> Right now: 1
> Right now: 2
> Right now: 3
> sb2: Regexp=SCALAR(0x814cc6c)
>
> The regular expression is somehow changed, and it seems to be storing my
> value in it, but compiled regular expressions can't contain numbers--can
> they?
You are dereferencing the value in $sb so you are not modifying its value but
what its value points to.
John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 19:02:32 von Uri Guttman
>>>>> "JWK" == John W Krahn writes:
JWK> No, when a reference is used as a number it becomes a number:
JWK> $ perl -le'$x = {}; print for ref $x, $x, $x + 0'
JWK> HASH
JWK> HASH(0x816cc20)
JWK> 135711776
you forgot to print $x after the +0.
perl -le'$x = {}; print for ref $x, $x, $x + 0, $x'
HASH
HASH(0x11d910)
1169680
HASH(0x11d910)
JWK> If you increment a reference it *becomes* a number and cannot be
JWK> changed back to a reference. Likewise, if you stringify a
JWK> reference it cannot be changed back to a reference.
incorrect.
perl -le'$x = {}; print for ref $x, $x, $x + 0, "$x", ref $x'
HASH
HASH(0x11d910)
1169680
HASH(0x11d910)
HASH
the stringified value can't be used as a ref but it doesn't change the
original value to a string. the ref is still valid there.
the difference with the OP's code is that ++ will change the ref value
to a number and store it back into $x and then the ref is lost
forever. just using a ref in some expression without modifiying it will
not change the ref.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 20:40:07 von someone
Uri Guttman wrote:
>>>>>>"JWK" == John W Krahn writes:
>
> JWK> No, when a reference is used as a number it becomes a number:
>
> JWK> $ perl -le'$x = {}; print for ref $x, $x, $x + 0'
> JWK> HASH
> JWK> HASH(0x816cc20)
> JWK> 135711776
>
> you forgot to print $x after the +0.
>
> perl -le'$x = {}; print for ref $x, $x, $x + 0, $x'
> HASH
> HASH(0x11d910)
> 1169680
> HASH(0x11d910)
>
> JWK> If you increment a reference it *becomes* a number and cannot be
> JWK> changed back to a reference. Likewise, if you stringify a
> JWK> reference it cannot be changed back to a reference.
>
> incorrect.
>
> perl -le'$x = {}; print for ref $x, $x, $x + 0, "$x", ref $x'
> HASH
> HASH(0x11d910)
> 1169680
> HASH(0x11d910)
> HASH
>
> the stringified value can't be used as a ref but it doesn't change the
> original value to a string. the ref is still valid there.
>
> the difference with the OP's code is that ++ will change the ref value
> to a number and store it back into $x and then the ref is lost
> forever. just using a ref in some expression without modifiying it will
> not change the ref.
That's what I thought I was saying. Unfortunately the code I used did not
convey that point. :)
John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
Re: Why does Tie::Simeple (scalar) work without real local data?
am 05.12.2006 20:51:20 von Uri Guttman
>>>>> "JWK" == John W Krahn writes:
JWK> Uri Guttman wrote:
>>>>>>> "JWK" == John W Krahn writes:
JWK> If you increment a reference it *becomes* a number and cannot be
JWK> changed back to a reference. Likewise, if you stringify a
JWK> reference it cannot be changed back to a reference.
>> the difference with the OP's code is that ++ will change the ref value
>> to a number and store it back into $x and then the ref is lost
>> forever. just using a ref in some expression without modifiying it will
>> not change the ref.
JWK> That's what I thought I was saying. Unfortunately the code I
JWK> used did not convey that point. :)
well you didn't say it in english either. the first quoted paragraph
above say stringifying will convert a ref and not be allowed to convert
back. i was correcting that and also the example code.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org