PERL MAP HELP

S

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
 
B

Brian McCauley

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} || []};
 
S

Subra

Thanks a lot Brian for detailed reply...
Its really helpful...


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} || []};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top