Thread: Plperl and my() lexical variables bug?

Plperl and my() lexical variables bug?

From
"Philippe Lang"
Date:
Hi,

I have something strange here, with Postgresql 8.1.4 under Linux ES 4, installed from the PG Group binaries:

If I run this script:

----------------
CREATE OR REPLACE FUNCTION foo() RETURNS void
AS
$$
    my $val;

    sub init
    {
    $val = @_[0];
    elog(NOTICE, "1: @_[0]\n");
    }

    &init(12);
    elog(NOTICE, "2: $val\n");
$$
LANGUAGE 'plperl';


select * from  foo();
----------------

I get in return something correct:

----------------
NOTICE:  1: 12

NOTICE:  2: 12


Total query runtime: 63 ms.
Data retrieval runtime: 62 ms.
1 rows retrieved.
----------------


But then, if I simply call the function, with:

----------------
select * from  foo();
----------------

I get:

----------------
NOTICE:  1: 12

NOTICE:  2:


Total query runtime: 63 ms.
Data retrieval runtime: 62 ms.
1 rows retrieved.
----------------

$val variable is missing.


Even more strange: if I replace "my $val;" with "$val;", this does not happen at all:

----------------
CREATE OR REPLACE FUNCTION foo() RETURNS void
AS
$$
    $val;

    sub init
    {
    $val = @_[0];
    elog(NOTICE, "1: @_[0]\n");
    }

    &init(12);
    elog(NOTICE, "2: $val\n");
$$
LANGUAGE 'plperl';
----------------

Now I can call the function with

----------------
select * from  foo();
----------------

it works as expected:

----------------
NOTICE:  1: 12

NOTICE:  2: 12


Total query runtime: 390 ms.
Data retrieval runtime: 797 ms.
1 rows retrieved.
----------------


Am I missing something maybe? It sounds like a bug with lexical variables to me...

Cheers,

----------------------------------
Philippe Lang, Ing. Dipl. EPFL
Attik System
rte de la Fonderie 2
1700 Fribourg
Switzerland
http://www.attiksystem.ch

Tel:  +41 (26) 422 13 75
Fax:  +41 (26) 422 13 76


Attachment

Re: Plperl and my() lexical variables bug?

From
Michael Fuhr
Date:
On Fri, Jun 23, 2006 at 11:33:42AM +0200, Philippe Lang wrote:
> Am I missing something maybe? It sounds like a bug with lexical variables to me...

I think what's happening is that sub init is created once with $val
referencing the lexically-scoped $val from sub foo's first invocation.
When you call foo again, foo creates a new lexically-scoped $val
but init's $val still refers to the object from foo's first call.
You can see this if you display \$val:

CREATE OR REPLACE FUNCTION foo() RETURNS void AS $$
    my $val;

    sub init {
        $val = $_[0];
        elog(NOTICE, "1: $_[0] " . \$val);
    }

    init(12);
    elog(NOTICE, "2: $val " . \$val);
$$ LANGUAGE plperl;

SELECT foo();
NOTICE:  1: 12 SCALAR(0x8447220)
NOTICE:  2: 12 SCALAR(0x8447220)
 foo
-----

(1 row)

SELECT foo();
NOTICE:  1: 12 SCALAR(0x8447220)
NOTICE:  2:  SCALAR(0x83f5c4c)
 foo
-----

(1 row)

This behavior isn't specific to PL/Perl.  A standalone Perl program
exhibits the same behavior, so you might find a better explanation
in a Perl-specific forum like the comp.lang.perl.misc newsgroup.

--
Michael Fuhr

Re: Plperl and my() lexical variables bug?

From
Martijn van Oosterhout
Date:
On Fri, Jun 23, 2006 at 07:49:19AM -0600, Michael Fuhr wrote:
> This behavior isn't specific to PL/Perl.  A standalone Perl program
> exhibits the same behavior, so you might find a better explanation
> in a Perl-specific forum like the comp.lang.perl.misc newsgroup.

If you run it standalone with warnings enabled, you get this:

Variable "$val" will not stay shared at a.pl line 6.

Which is pretty much what is happening. There's plenty written about
this on the web. This has a good summary as well as solutions:

http://perl.com/pub/a/2002/05/07/mod_perl.html

In particular, if you "use diagnostics" it suggests an anonymous sub
will deal with it.

Hope this helps,

---- a.pl ----
use warnings;
use diagnostics;

sub test
{
    my $val;

    sub init {
        $val = $_[0];
        print( "1: $_[0] " . \$val . "\n");
    }

    init(12);
    print("2: $val " . \$val . "\n");

}

test;
test;
--- snip ---
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Attachment