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