PERL MAP HELP
am 19.01.2008 13:03:29 von Subra
Hi,
Can some one tell me how the below code works ???
605: @cherou= map {
606: ($nf,@narg)=split(/:/,$_);
607: &{$::{"setup_$nf"}}($type,@narg); #returns the
subformat above
608: } exists $setupstuff{$ap} ? @{$setupstuff{$ap}} :
() ;
And also pls let me know wts mean by &{$::{"setup_$nf"}}
($type,@narg).
Is $:: used to access the defs from the other packages ???
Best Regards,
Sburam
Re: PERL MAP HELP
am 19.01.2008 14:58:53 von nobull67
On Jan 19, 12:03 pm, Subra wrote:
> Hi,
>
> Can some one tell me how the below code works ???
An explanation of the sematics of...
map { BLOCK } LIST
....can be found in the Perl reference manual.
If there's anything you find unclear in there please let us know what.
Any off-the-cuff explanation that someone could post to a newsgroup is
unlikely to be better than the one in the manual.
> 605: @cherou= map {
> 606: ($nf,@narg)=split(/:/,$_);
> 607: &{$::{"setup_$nf"}}($type,@narg); #returns the
> subformat above
> 608: } exists $setupstuff{$ap} ? @{$setupstuff{$ap}} :
> () ;
>
> And also pls let me know wts mean by &{$::{"setup_$nf"}}
> ($type,@narg).
>
> Is $:: used to access the defs from the other packages ???
$::{ whatever } is actually a simply a hash lookup in the special hash
called %:: which is the root of the Perl symbol table. %:: is actually
the same hash as %main:: which is the symbol table of the default
package 'main'. Using this syntax you can only access symbols form
the default package main.
Therefore supping $nf='foo' the expression $::{"setup_$nf"} therefore
returns the symbol table entry (GLOB) from the package main for the
symbol setup_foo (aka *main::setup_foo ). Indeed $::{"setup_$nf"} is
almost the same as saying *{"main::setup_$nf"} except using the
explicit symbolic GLOBref will auto-vivify the GLOB and makes the
intent much clearer.
&{ whatever } will they coerce whatever into a CODEref. Since whatever
is *main::setup_foo the whatever gets coerced into
*main::setup_foo{CODE} aka \&main::setup_foo.
&{$::{"setup_$nf"}}($type,@narg) is therefore equivalent to
main::setup_foo($type,@narg). OK that's a slight simplification in
that I'm assuming &main::setup_foo doesn't have a prototype - usually
a safe assumption.
All in all I'd just say
"main::setup_$nf"->($type,@narg);
Now, I hear you all (and indeed strict.pm) cry "you're using symrefs".
Yes I am. So I'd need actually to say:
no strict 'refs';
"main::setup_$nf"->($type,@narg);
But it is important to note is that using symrefs is not evil just
because some pseudo-deity declared that it should be the case. It's
evil because mucking about with the symbol table is fraught with
dangers. If you are going to do this anyhow then do it with the
simplest syntax Perl offers and put a nice big red flag "no strict" so
that it is obvious what you're doing. Don't go using a more obfuscated
approach to avoid the need for "no strict".
Also the construct
exits( EXPR )? @{ EXPR } : ();
Seems unduly complex. If EXPR does not exist then it'll also be false
so it's simpler to say
@{ EXPR || [] };
Oh, and the original code was missing at least one my().
my @cherou= map {
my ($nf,@narg)=split /:/;
no strict 'refs';
"main::setup_$nf"->($type,@narg);
} @{$setupstuff{$ap} || []};
Re: PERL MAP HELP
am 20.01.2008 15:13:55 von Subra
Thanks a lot Brian for detailed reply...
Its really helpful...
On Jan 19, 6:58 pm, Brian McCauley wrote:
> On Jan 19, 12:03 pm, Subra wrote:
>
> > Hi,
>
> > Can some one tell me how the below code works ???
>
> An explanation of the sematics of...
>
> map { BLOCK } LIST
>
> ...can be found in the Perl reference manual.
>
> If there's anything you find unclear in there please let us know what.
>
> Any off-the-cuff explanation that someone could post to a newsgroup is
> unlikely to be better than the one in the manual.
>
> > 605: @cherou= map {
> > 606: ($nf,@narg)=split(/:/,$_);
> > 607: &{$::{"setup_$nf"}}($type,@narg); #returns the
> > subformat above
> > 608: } exists $setupstuff{$ap} ? @{$setupstuff{$ap}} :
> > () ;
>
> > And also pls let me know wts mean by &{$::{"setup_$nf"}}
> > ($type,@narg).
>
> > Is $:: used to access the defs from the other packages ???
>
> $::{ whatever } is actually a simply a hash lookup in the special hash
> called %:: which is the root of the Perl symbol table. %:: is actually
> the same hash as %main:: which is the symbol table of the default
> package 'main'. Using this syntax you can only access symbols form
> the default package main.
>
> Therefore supping $nf='foo' the expression $::{"setup_$nf"} therefore
> returns the symbol table entry (GLOB) from the package main for the
> symbol setup_foo (aka *main::setup_foo ). Indeed $::{"setup_$nf"} is
> almost the same as saying *{"main::setup_$nf"} except using the
> explicit symbolic GLOBref will auto-vivify the GLOB and makes the
> intent much clearer.
>
> &{ whatever } will they coerce whatever into a CODEref. Since whatever
> is *main::setup_foo the whatever gets coerced into
> *main::setup_foo{CODE} aka \&main::setup_foo.
>
> &{$::{"setup_$nf"}}($type,@narg) is therefore equivalent to
> main::setup_foo($type,@narg). OK that's a slight simplification in
> that I'm assuming &main::setup_foo doesn't have a prototype - usually
> a safe assumption.
>
> All in all I'd just say
>
> "main::setup_$nf"->($type,@narg);
>
> Now, I hear you all (and indeed strict.pm) cry "you're using symrefs".
> Yes I am. So I'd need actually to say:
>
> no strict 'refs';
> "main::setup_$nf"->($type,@narg);
>
> But it is important to note is that using symrefs is not evil just
> because some pseudo-deity declared that it should be the case. It's
> evil because mucking about with the symbol table is fraught with
> dangers. If you are going to do this anyhow then do it with the
> simplest syntax Perl offers and put a nice big red flag "no strict" so
> that it is obvious what you're doing. Don't go using a more obfuscated
> approach to avoid the need for "no strict".
>
> Also the construct
> exits( EXPR )? @{ EXPR } : ();
>
> Seems unduly complex. If EXPR does not exist then it'll also be false
> so it's simpler to say
>
> @{ EXPR || [] };
>
> Oh, and the original code was missing at least one my().
>
> my @cherou= map {
> my ($nf,@narg)=split /:/;
> no strict 'refs';
> "main::setup_$nf"->($type,@narg);
> } @{$setupstuff{$ap} || []};