Named nested subroutines?

Discussion in 'Perl Misc' started by Rainer Weikusat, Oct 25, 2011.

  1. Are the other gotchas with named nested subroutines than the 'variable
    will not stay shared' issue?
    Rainer Weikusat, Oct 25, 2011
    #1
    1. Advertising

  2. Rainer Weikusat wrote:
    > Are the other gotchas with named nested subroutines than the 'variable
    > will not stay shared' issue?


    Named subroutines cannot be "nested" because their names are package
    variables and so do not follow lexical scoping rules.

    The problem you are having is with lexical variables that are in the
    wrong scope.



    John
    --
    Any intelligent fool can make things bigger and
    more complex... It takes a touch of genius -
    and a lot of courage to move in the opposite
    direction. -- Albert Einstein
    John W. Krahn, Oct 26, 2011
    #2
    1. Advertising

  3. "John W. Krahn" <> writes:
    > Rainer Weikusat wrote:
    >> Are the other gotchas with named nested subroutines than the 'variable
    >> will not stay shared' issue?

    >
    > Named subroutines cannot be "nested" because their names are package
    > variables and so do not follow lexical scoping rules.


    To a degree, they can

    ----------
    #!/usr/bin/perl

    sub blubb
    {
    return 'blubb';
    }

    sub blah
    {
    local *blubb = sub { return 'yadda'; };
    return blubb();
    }

    print blubb(), " ", blah(), "\n";
    ----------

    but I was asking about named subroutines defined
    inside other named subroutines, eg

    sub a
    {
    sub b { return 1; }
    return 2;
    }

    specifically, because I'm using PL/Perl (Perl as PostgreSQL
    procedural language) for a task which isn't entirely trivial anymore
    and I would like to avoid having to put all my helper subs as
    anonymous subroutines into %_SHARED and invoking them by going through
    this hash. The PL/Perl documentation recommends against this,
    calling it 'dangerous' and referring to perldiag for details. But the
    only thing this manpage has to say to that is the 'variable will
    not stay shared' issue[*] which doesn't affect me because I need to
    put definitions of named subroutines into an anonymous Perl
    subroutine (PL/Perl top-level construct) but all I want is creating
    functions with ordinary names which can be invoked as usual.

    [*] Not that this would really be true (tested with 5.10.1,
    known to be working for some older version as well):

    ----------------
    sub howl
    {
    my $x;

    $x = 2;

    {
    sub yodel { return $x; }
    }

    return sub { ++$x; };
    }

    my $inc = howl();

    print yodel, "\n";
    $inc->();
    print yodel, "\n";
    $inc->();
    print yodel, "\n";
    -----------------

    [rw@sapphire]/tmp $perl -w a.pl
    Variable "$x" will not stay shared at a.pl line 9.
    2
    3
    4
    Rainer Weikusat, Oct 26, 2011
    #3
  4. Ben Morrow <> writes:
    > Quoth Rainer Weikusat <>:
    >> "John W. Krahn" <> writes:
    >> > Rainer Weikusat wrote:


    [...]

    >> sub howl
    >> {
    >> my $x;
    >>
    >> $x = 2;
    >>
    >> {
    >> sub yodel { return $x; }
    >> }
    >>
    >> return sub { ++$x; };
    >> }
    >>
    >> my $inc = howl();
    >>
    >> print yodel, "\n";
    >> $inc->();
    >> print yodel, "\n";
    >> $inc->();
    >> print yodel, "\n";

    >
    > my $again = howl();
    > say(yodel), $again->() for 1..3;
    >
    > You only called &howl once, so there was only ever one copy of $x and
    > therefore no problem. The problem arises when you call it again, so
    > there are now two copies of $x, so it's no longer clear which copy the
    > global &yodel should refer to.


    Unless it is redefined (which it isn't), it should continue to refer to the same $x it
    originally referred to. After all, the closure created by a 2nd
    invocation also won't "share" an $x with the closure created by the
    first one. But I certainly misunderstood the warning ...
    Rainer Weikusat, Oct 26, 2011
    #4
  5. Ben Morrow <> writes:

    [...]

    > The subs are actually defined at (Perl) compile time, so depending on
    > exactly when Pg passes the string to perl to be compiled you may find
    > you don't need to *run* setup_subs() at all, just CREATE it. You may
    > also find this is unpredictable and depends on exactly which perl
    > instance you end up with each time; I don't know the details of when Pg
    > passes which functions to which Perl instances, but it may be that if
    > you haven't run setup_subs() in this session this Perl interpreter won't
    > have seen the definition at all.


    For 'interpreted' procedural language routines, it just stores the
    source code in the pg_proc table and passes it to the Perl
    interpreter associated with the current session (for Linux/UNIX(*)),
    this means 'the process handling the client connection') either when
    the subroutine needs to be executed for the first time or after the
    defining command was encountered.

    > [Being an evil-minded person, it occurs to me at this point to wonder
    > what happens if you say
    >
    > CREATE FUNCTION setup_subs() RETURNS void AS $$
    > };
    >
    > sub foo { ... }
    > sub bar { ... }
    >
    > sub {
    > $$ LANGUAGE plperl;
    >
    > Little Bobby Tables, and so on...]


    The source code is really just wrapped into sub { }, cf

    [rw@splittermine]/tmp $sudo -u postgres psql -U postgres -d mad_database
    psql (8.4.8)
    Type "help" for help.

    mad_database=# create or replace function pltest() returns integer as $$ }; sub aaa { return 12; } sub { return aaa(); $$ language plperlu;
    CREATE FUNCTION
    mad_database=# select pltest();
    pltest
    --------
    12
    (1 row)
    mad_database=# \q
    [rw@splittermine]/tmp $sudo -u postgres psql -U postgres -d mad_database
    psql (8.4.8)
    Type "help" for help.

    mad_database=# create or replace function pltest2() returns integer as $$ return aaa(); $$ language plperlu;
    CREATE FUNCTION
    mad_database=# select pltest2();
    ERROR: error from Perl function "pltest2": Undefined subroutine &main::aaa called at line 1.
    mad_database=# select pltest();
    pltest
    --------
    12
    (1 row)

    mad_database=# select pltest2();
    pltest2
    ---------
    12
    (1 row)
    Rainer Weikusat, Oct 26, 2011
    #5
    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. ReaprZero

    References and subroutines

    ReaprZero, Dec 4, 2003, in forum: Perl
    Replies:
    1
    Views:
    447
    Gunnar Hjalmarsson
    Dec 4, 2003
  2. MackS
    Replies:
    0
    Views:
    466
    MackS
    Mar 11, 2005
  3. tshad

    Global subroutines

    tshad, Jan 24, 2005, in forum: ASP .Net
    Replies:
    7
    Views:
    373
    IPGrunt
    Jan 26, 2005
  4. joe

    Nested subroutines

    joe, Apr 9, 2005, in forum: ASP General
    Replies:
    3
    Views:
    211
  5. Replies:
    9
    Views:
    119
    Eric Bohlman
    Oct 19, 2005
Loading...

Share This Page