in reply to Perl templating/macro creating using 'BEGIN'...

The reason your subroutines are not defined in your package 'MyPackage' is that your subroutines are being defined in package main, rather than in package MyPackage. Even though you use a reference to the subroutine main_package_vars that is defined in package MyPackage (i.e. package_vars3) the subroutine (main_package_vars) still runs in the context of package main and the subroutines it defines are defined in package main.

By using fully qualified names, you can create the subroutines in any package name space. One option is to use __PACKAGE__ to pass the name of your package to main_package_vars and use this to create fully qualified names.

You might also be interested to use Data::Dumper to inspect the namespace of your package.

Here is a modified version of one of your code samples that might help you understand what is happening:

#!/usr/bin/perl -w use strict; use feature ':5.10'; BEGIN { sub package_vars { my $package = shift; foreach(@_) { eval "sub ${package}::$_ { my \$p = shift; \$p->{$_} = \$_[0] if \@_; \$p->{$_}; }" } } } package MyPackage; use Data::Dumper; { main::package_vars( __PACKAGE__, qw(one two three) ); print Dumper(\%MyPackage::); sub new { my $package=shift; my $parms=$_[0]; my $this={}; foreach(%$parms) { $this->{$_}=$parms->{$_}; } bless $this, $package; } } package main; my $p=new MyPackage({three => 3,}); $p->two(1); printf "two=%d, three=%d\n",$p->two, $p->three;

Replies are listed 'Best First'.
Re^2: Perl templating/macro creating using 'BEGIN'...
by perl-diddler (Chaplain) on Sep 27, 2010 at 20:16 UTC
    That's exactly what I want to do -- thank you for your understanding my question! However ... (sigh),... how can I do it without explicitly passing "__PACKAGE_" at the point of call. How can I tell what package 'main_package_vars' is called invoked from w/o explicitly passing it the package name?

    After reading your response, I tried some way of delaying the interpretation of '__PACKAGE__' to interpret it at expansion time, below, but I think I keep ending up with 'two' in main or in the packaged named '__PACKAGE__', which is no help! If you see what I mean...?

    I.e., if I was using some package like Class::Accessor, I don't see, yet, how it is getting the current package name and putting the routines into the current package's name space, but this is definitely the direction I'm looking for...maybe I just need to play around with this idea a bit and I'll bump into it...(?)...

      The ->import subroutine that is called from a use statement can find out the name of the calling package by using caller.

        Yup, this works:
        #!/usr/bin/perl -w #use strict; use feature ':5.10'; BEGIN { sub package_vars { my $pck=caller; foreach(@_) { eval "sub ${pck}::$_ { my \$p = shift; \$p->{$_} = \$_[0] if \@_; \$p->{$_}; }" } } } package MyPackage; *package_vars=\&main::package_vars; { package_vars( qw(one two three) ); sub new { my $package=shift; my $parms=$_[0]; my $this={}; foreach(%$parms) { $this->{$_}=$parms->{$_}; } bless $this, $package; } } package main; my $p=new MyPackage({three => 3,}); $p->two(1); printf "two=%d, three=%d\n",$p->two, $p->three;
        Yeah!

        Now I understand how this works and can write my own 'macros' as needed rather than trying to find some specialized package to write the macro I want...

        Thanks all!