In a recent post I mentioned that I had a PLPERL procedure that ...adds useful definitions, mostly subs, to Perl's main package.
I thought this claim needs further clarification, since the docs for PLPERL include a warning that may give readers the impression that defining Perl functions within PLPERL code is somehow problematic. This warning says: Note: The use of named nested subroutines is dangerous in Perl, especially > if they refer to lexical variables in the enclosing scope. Because a PL/Perl > function is wrapped in a subroutine, any named subroutine you create will be > nested. In general, it is far safer to create anonymous subroutines which > you call via a coderef. > But this is only a problem if one defines functions like this sub foo { # blah blah blah } which indeed would result in a nested function. But one can define non-nested functions within other functions (and even "closures" that refer to lexical variables) by manipulating symbol tables directly. For example: CREATE FUNCTION make_closure ( TEXT ) RETURNS void AS $PERL$ my $lexical = shift; *the_closure = sub { return '>> ' . $lexical }; $PERL$ LANGUAGE plperl IMMUTABLE; CREATE FUNCTION test_closure () RETURNS TEXT AS $PERL$ return the_closure(); $PERL$ LANGUAGE plperl VOLATILE; First, we show that the perl function the_closure (or more precisely, main::the_closure) has not been defined yet. SELECT * from test_closure(); ERROR: error from Perl function: Undefined subroutine &main::the_closure called at line 2. As expected. To define the perl function the_closure, we need to call make_closure first: SELECT make_closure( 'foobar' ); SELECT * from test_closure(); test_closure -------------- >> foobar (1 row) Now the PLPERL procedure test_closure() can invoke the perl function the_closure. The next (very contrived) example demonstrates that the functions being defined are indeed closures (note that each of the Perl functions defined through calls to make_closure2 refers to its own private copy of the variable $lexical). (Note that this example uses a "soft reference", but one can achieve the same thing by eval'ing a suitable string). CREATE FUNCTION make_closure2 ( TEXT, TEXT ) RETURNS void AS $PERL$ my $closure_name = shift; my $lexical = shift; *{ $closure_name } = sub { return '>> ' . $lexical }; return; $PERL$ LANGUAGE plperlu IMMUTABLE; CREATE FUNCTION test_closure2 ( TEXT ) RETURNS TEXT AS $PERL$ my $ret = eval( shift() . '()' ); die if $@; return $ret; $PERL$ LANGUAGE plperlu VOLATILE; SELECT make_closure2( 'first_closure', 'quux' ); SELECT make_closure2( 'second_closure', 'frobozz' ); SELECT * FROM test_closure2( 'first_closure' ); test_closure2 --------------- >> quux (1 row) SELECT * FROM test_closure2( 'second_closure' ); test_closure2 --------------- >> frobozz (1 row) And the functions need not to be defined in the main package. For example, make_closure3 is exactly like make_closure above, except that it defines the function the_closure in the package Some::Other::Package rather than the package main. (Similarly, test_closure3 is exactly like test_closure, except that it invokes Some::Other::Package::the_closure rather than main::the_closure.) CREATE FUNCTION make_closure3 ( TEXT ) RETURNS void AS $PERL$ my $lexical = shift; *Some::Other::Package::the_closure = sub { return '>> ' . $lexical }; $PERL$ LANGUAGE plperl IMMUTABLE; CREATE FUNCTION test_closure3 () RETURNS TEXT AS $PERL$ return Some::Other::Package::the_closure(); $PERL$ LANGUAGE plperl VOLATILE; SELECT make_closure3( 'mwa-ha-ha-ha-ha!' ); SELECT * from test_closure3(); test_closure3 --------------------- >> mwa-ha-ha-ha-ha! (1 row) I want to point out that such symbol-table manipulations are entirely standard. For example, the standard Perl module Exporter uses this technique to install functions and variables in the calling package's namespace. Kynn