vec() in lvalue sub

Discussion in 'Perl Misc' started by s · reservoir, Aug 13, 2008.

  1. 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, Aug 13, 2008
    #1
    1. Advertising

  2. 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, Aug 13, 2008
    #2
    1. Advertising

  3. > 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.
     
    s · reservoir, Aug 13, 2008
    #3
  4. 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
     
    Leon Timmermans, Aug 13, 2008
    #4
  5. On Aug 13, 3:03 pm, Leon Timmermans <> 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, Aug 13, 2008
    #5
  6. On Aug 13, 3:03 pm, Leon Timmermans <> 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;
     
    s · reservoir, Aug 13, 2008
    #6
  7. s · reservoir

    Ben Morrow Guest

    Quoth =?ISO-8859-1?Q?s_=B7_reservoir?= <>:
    > 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.
    Frank Herbert, 'Dune'
     
    Ben Morrow, Aug 13, 2008
    #7
  8. 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/perlsub.pod#Lvalue_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.
     
    s · reservoir, Aug 15, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kavya
    Replies:
    9
    Views:
    525
    Dik T. Winter
    Oct 28, 2006
  2. er
    Replies:
    6
    Views:
    500
    Andre Kostur
    Sep 14, 2007
  3. Replies:
    11
    Views:
    710
    James Kuyper
    Sep 22, 2008
  4. Ioannis Vranos

    (&vec)== &vec[0]?

    Ioannis Vranos, Sep 30, 2008, in forum: C++
    Replies:
    5
    Views:
    434
    Juha Nieminen
    Oct 1, 2008
  5. Julian Mehnle
    Replies:
    0
    Views:
    246
    Julian Mehnle
    Jul 17, 2003
Loading...

Share This Page