Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   vec() in lvalue sub (http://www.velocityreviews.com/forums/t908082-vec-in-lvalue-sub.html)

 s · reservoir 08-13-2008 05:21 PM

vec() in lvalue sub

The subroutine is this:
sub mess_with_bits(\\$\$;\$) : lvalue {
do {
eval {
\${\$_[0]} = ''
};
cluck \$@ if \$@;
} if (!defined \${\$_[0]});
my \$r = shift;
my \$p = shift;
if (@_) {
my \$o = vec(\$\$r => \$p, 1);
vec(\$\$r => \$p, 1) = shift;
return \$o;
}
vec(\$\$r => \$p, 1);
}
But when I do this:
mess_with_bits(\$str, 17) = 1;
print mess_with_bits(\$str, 2), "\n"'
it prints 1.

 s · reservoir 08-13-2008 05:25 PM

Re: vec() in lvalue sub

s · reservoir wrote:
> The subroutine is this:
> sub mess_with_bits(\\$\$;\$) : lvalue {
> do {
> eval {
> \${\$_[0]} = ''
> };
> cluck \$@ if \$@;
> } if (!defined \${\$_[0]});
> my \$r = shift;
> my \$p = shift;
> if (@_) {
> my \$o = vec(\$\$r => \$p, 1);
> vec(\$\$r => \$p, 1) = shift;
> return \$o;
> }
> vec(\$\$r => \$p, 1);
> }
> But when I do this:
> mess_with_bits(\$str, 17) = 1;
> print mess_with_bits(\$str, 2), "\n"'
> it prints 1.

For some reason, it prints 0 if I don't have
use feature qw(say);

 s · reservoir 08-13-2008 05:28 PM

Re: vec() in lvalue sub

> For some reason, it prints 0 if I don't have
> use feature qw(say);

I take that back. For some reason, it still doesn't seem to work.

 Leon Timmermans 08-13-2008 07:03 PM

Re: vec() in lvalue sub

On Wed, 13 Aug 2008 13:21:00 -0400, s Â· reservoir wrote:

> The subroutine is this:
> sub mess_with_bits(\\$\$;\$) : lvalue {
> do {
> eval {
> \${\$_[0]} = ''
> };
> cluck \$@ if \$@;
> } if (!defined \${\$_[0]});
> my \$r = shift;
> my \$p = shift;
> if (@_) {
> my \$o = vec(\$\$r => \$p, 1);
> vec(\$\$r => \$p, 1) = shift;
> return \$o;
> }
> vec(\$\$r => \$p, 1);
> }
> But when I do this:
> mess_with_bits(\$str, 17) = 1;
> print mess_with_bits(\$str, 2), "\n"'
> it prints 1.

No offense, but this is terrible code to read. The `do{} if` thing
doesn't make any sense at all, why not just use an if statement? Why do
you use an eval section? Also, please give your variables normal names.

Anyway, I can reproduce this (on 5.8.8). The value in the bitstring is 0,
but the function reports 1. Smells like a bug to me.

Regards,

Leon Timmermans

 s · reservoir 08-13-2008 08:13 PM

Re: vec() in lvalue sub

On Aug 13, 3:03*pm, Leon Timmermans <faw...@gmail.com> wrote:
> On Wed, 13 Aug 2008 13:21:00 -0400, s · reservoir wrote:
> > The subroutine is this:
> > sub mess_with_bits(\\$\$;\$) : lvalue {
> > * *do {
> > * * *eval {
> > * * * *\${\$_[0]} = ''
> > * * *};
> > * * *cluck \$@ if \$@;
> > * *} if (!defined \${\$_[0]});
> > * *my \$r = shift;
> > * *my \$p = shift;
> > * *if (@_) {
> > * * *my \$o = vec(\$\$r => \$p, 1);
> > * * *vec(\$\$r => \$p, 1) = shift;
> > * * *return \$o;
> > * *}
> > * *vec(\$\$r => \$p, 1);
> > }
> > But when I do this:
> > * *mess_with_bits(\$str, 17) = 1;
> > * *print mess_with_bits(\$str, 2), "\n"'
> > it prints 1.

>
> No offense, but this is terrible code to read. The `do{} if` thing
> doesn't make any sense at all, why not just use an if statement? Why do

It is terrible. I was going to rewrite it, but I never got around to
it.
Thanks for reminding me.

> you use an eval section? Also, please give your variables normal names.

In case somebody tried mess_with_bits('', 17). It has to do with an
old
implementation of it that I never really fixed.

> Anyway, I can reproduce this (on 5.8.8). The value in the bitstring is 0,
> but the function reports 1. Smells like a bug to me.

Sent a report with perlbug.

 s · reservoir 08-13-2008 09:29 PM

Re: vec() in lvalue sub

On Aug 13, 3:03*pm, Leon Timmermans <faw...@gmail.com> wrote:
> On Wed, 13 Aug 2008 13:21:00 -0400, s · reservoir wrote:
> > The subroutine is this:
> > sub mess_with_bits(\\$\$;\$) : lvalue {
> > * *do {
> > * * *eval {
> > * * * *\${\$_[0]} = ''
> > * * *};
> > * * *cluck \$@ if \$@;
> > * *} if (!defined \${\$_[0]});
> > * *my \$r = shift;
> > * *my \$p = shift;
> > * *if (@_) {
> > * * *my \$o = vec(\$\$r => \$p, 1);
> > * * *vec(\$\$r => \$p, 1) = shift;
> > * * *return \$o;
> > * *}
> > * *vec(\$\$r => \$p, 1);
> > }
> > But when I do this:
> > * *mess_with_bits(\$str, 17) = 1;
> > * *print mess_with_bits(\$str, 2), "\n"'
> > it prints 1.

>
> No offense, but this is terrible code to read. The `do{} if` thing
> doesn't make any sense at all, why not just use an if statement? Why do
> you use an eval section? Also, please give your variables normal names.
>
> Anyway, I can reproduce this (on 5.8.8). The value in the bitstring is 0,
> but the function reports 1. Smells like a bug to me.

Oddly enough, this works:

#!/usr/bin/env perl
use strict;
use warnings;
sub f(\\$\$;\$) : lvalue {
do { eval { \${\$_[0]} = '' }; warn \$@ if \$@; } if (!defined \$
{\$_[0]});
my \$r = shift;
my \$p = shift;
if (@_) {
my \$o = vec(\$\$r => \$p, 1);
vec(\$\$r => \$p, 1) = shift;
return \$o;
}
vec(\$\$r => \$p, 1);
}
sub say {
print @_, "\n";
}
my \$str;
say f(\$str => 13);
f(\$str => 17) = 1;
my \$t = f(\$str => 13);
say \$t;

 Ben Morrow 08-13-2008 09:50 PM

Re: vec() in lvalue sub

Quoth =?ISO-8859-1?Q?s_=B7_reservoir?= <sreservoir@gmail.com>:
> The subroutine is this:
> sub mess_with_bits(\\$\$;\$) : lvalue {

lvalue subs do not always behave as one might expect, and are worth
avoiding. What's wrong with a more normal API?

Ben

--
I must not fear. Fear is the mind-killer. I will face my fear and
I will let it pass through me. When the fear is gone there will be
nothing. Only I will remain.
ben@morrow.me.uk Frank Herbert, 'Dune'

 s · reservoir 08-15-2008 12:13 AM

Re: vec() in lvalue sub

Big and Blue wrote:
> In 5.8.5 it also reports 1....

As it does under 5.6.3, 5.7.3, 5.8.8, 5.9.4, and 5.10.0...

> FWIW the "if (@_)" setting block never gets called (put a print
> statement in it - it never happens). The first call only has 2
> parameters. Hence \$str is never set, and you are actually trying to

\$str is should set - the ugly do if block assigns to it, not the if (@_).

> access an unset variable, which probably explains the different result

Access to an unset variable gives a warning under -w, but it didn't.

> in and not-in the debugger.

The if (@_) block is there to let you do this:
mess_with_bits(\$str, 1, 1);
and get back 0 while setting the second bit to 1.
I just copied most of it from my editor.

> It is documented that you can't have a return in an lvalue sub (e.g.
> http://search.cpan.org/dist/perl/pod..._subroutines__)

Though in reality, you can - you just can't assign to it if it returns
from a return. I discovered that when I foolishly tried to do so.

 All times are GMT. The time now is 06:28 AM.