Messages 1-10 from thread |
Next 6
Jump to [ End of thread ]
Hello,
I'm trying to use a variable in the name of a subroutine, like so:
foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
if ($res = _send_$x($domain, $file, $date, $location)) {
push (@results, $res);
}
sub _send_email_zip {
}
sub _send_email_txt{
}
etc...
However, I'm getting the following error message:
"Can't locate object method "_send_" via package "email_zip" (perhaps you forgot to load
"email_zip"?)"
So, then I thought I could use the whole subroutine name in the foreach
loop: ("_send_email_zip", "_send_email_txt", etc), but I cannot figure
out if there is a way to get this to work.
Does anyone know of a way to use a variable in the name of a subroutine?
Thanks,
Kristina Clair
Kristina Clair wrote:
>
> Hello,
>
> I'm trying to use a variable in the name of a subroutine, like so:
>
> foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
> if ($res = _send_$x($domain, $file, $date, $location)) {
Replace that last line with these two:
my $com = "_send_$x";
if ($res = &$com($domain, $file, $date, $location)) {
--
Jeff
>>>>> "JZ" == Jeff Zucker <jeff@vpservices.com> writes:
>> I'm trying to use a variable in the name of a subroutine, like so:
>>
>> foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
>> if ($res = _send_$x($domain, $file, $date, $location)) {
JZ> Replace that last line with these two:
JZ> my $com = "_send_$x";
JZ> if ($res = &$com($domain, $file, $date, $location)) {
i was hoping no one would give a symbolic ref answer. too bad but you
just did. a dispatch table (hash of names to sub refs) is the best way
to do this.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite -
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Uri Guttman wrote:
>
> >>>>> "JZ" == Jeff Zucker <jeff@vpservices.com> writes:
> >> I'm trying to use a variable in the name of a subroutine, like so:
> >>
> >> foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
> >> if ($res = _send_$x($domain, $file, $date, $location)) {
>
> JZ> Replace that last line with these two:
>
> JZ> my $com = "_send_$x";
> JZ> if ($res = &$com($domain, $file, $date, $location)) {
>
> i was hoping no one would give a symbolic ref answer. too bad but you
> just did. a dispatch table (hash of names to sub refs) is the best way
> to do this.
Yes, duh. I was looking at the small picture of why _send_$x()
wouldn't work because there was no concatenation. You are of course
correct about it being a bad answer in the bigger picture.
--
Jeff
You could put a whole sub name in a var (symbolic ref), but not part of a
name (interpolation).
But don't do that. Instead, get (hard) refs to the subs and process a list
of refs:
$email_zip = \&_send_email_zip; # take hte refs
$email_txt = \&_send_email_txt;
($domain, $file, $date, $location) = qw(domain file date location); # just
so there's someoutput
foreach my $x ($email_zip, $email_txt) {
if ($res = &$x($domain, $file, $date, $location)) {
push (@results, $res);
}
}
print join " ", "results", @results, "\n";
sub _send_email_zip {
print join " ", "zip", @_, "\n";
}
sub _send_email_txt {
print join " ", "txt", @_, "\n";
}
... prints...
zip domain file date location
txt domain file date location
results 1 1
"Kristina Clair" <kclair@soya.serve.com> wrote in message
news:9s9747$r4j@netaxs.com...
> Hello,
>
> I'm trying to use a variable in the name of a subroutine, like so:
>
> foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
> if ($res = _send_$x($domain, $file, $date, $location)) {
> push (@results, $res);
> }
>
> sub _send_email_zip {
Read the rest of this message... (25 more lines)
Kristina Clair wrote:
>
> I'm trying to use a variable in the name of a subroutine, like so:
>
> foreach my $x ("email_zip", "email_txt", "cp_zip", "cp_txt") {
> if ($res = _send_$x($domain, $file, $date, $location)) {
Ack! What you're trying to do is use a symbolic reference. Trust me, you
don't really want to do that. Use hard references instead:
my %send = (
email_zip => \&_send_email_zip,
email_txt => \&_send_email_txt,
cp_zip => \&_send_cp_zip,
cp_txt => \&_send_cp_txt,
);
foreach my $x (qw/email_zip email_txt cp_zip cp_txt/) {
if ($res = $send{$x}->($domain, $file, $date, $location)) {
# ...
}
}
-mjc
In article <3BE83084.ACC43E8D@home.com>,
Michael Carman <mjcarman@home.com> wrote:
>Ack! What you're trying to do is use a symbolic reference. Trust me, you
>don't really want to do that.
I'm not clear on why not. So far three people have said "you don't
want to do that" without explaining what the problem might be.
What's the problem?
> my %send = (
> email_zip => \&_send_email_zip,
> email_txt => \&_send_email_txt,
> cp_zip => \&_send_cp_zip,
> cp_txt => \&_send_cp_txt,
> );
I think this comes under the heading of what Michael Schwern likes to
call "Monkey Code". You have a table with four entries that encodes
essentially no information. What's the benefit here?
This is a serious question, by the way.
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print
>>>>> "MJD" == Mark Jason Dominus <mjd@plover.com> writes:
MJD> In article <3BE83084.ACC43E8D@home.com>,
MJD> Michael Carman <mjcarman@home.com> wrote:
>> Ack! What you're trying to do is use a symbolic reference. Trust me, you
>> don't really want to do that.
MJD> I'm not clear on why not. So far three people have said "you don't
MJD> want to do that" without explaining what the problem might be.
MJD> What's the problem?
>> my %send = (
>> email_zip => \&_send_email_zip,
>> email_txt => \&_send_email_txt,
>> cp_zip => \&_send_cp_zip,
>> cp_txt => \&_send_cp_txt,
>> );
MJD> I think this comes under the heading of what Michael Schwern
MJD> likes to call "Monkey Code". You have a table with four entries
MJD> that encodes essentially no information. What's the benefit
MJD> here?
MJD> This is a serious question, by the way.
you wrote the varvar series of articles. it is the same problem. what if
some random string ws passed in from the outside and a bad sub was
called? at least check the sub name against a hash for verification. and
there is no guarantee that the string name will always be a substring of
the sub name and in the same place in the name. a hash allows freedom to
map different names to subs. using the symbol table is not appropriate
for this as there may be many more possible subs there than you want to
allow. a dispatch table allows this to work under use strict which is a
benefit as well and i believe it will untaint a sub name too.
it doesn't matter that subs are being used here instead of variables,
symrefs can lead to all sorts of hard to fix problems and are
obsfucating at best even when they work
are those enough reasons?
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite -
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
In article <x74ro7v8ti.fsf@home.sysarch.com>,
Uri Guttman <uri@stemsystems.com> wrote:
> MJD> What's the problem?
>
>you wrote the varvar series of articles. it is the same problem.
It isn't; none of the problems I discussed in those articles applies
here. That is why I asked the question.
>what if some random string was passed in from the outside
That is evidently not the case here. The four strings were hardwired
into a compile-time list constant.
>at least check the sub name against a hash for verification.
I do not see the purpose of checking members of a compile-time list
against the keys of a compile-time hash for verification. If you
don't trust the list, why would you trust the hash? Why wouldn't you
check the hash keys against a second hash, just to be double sure?
>and there is no guarantee that the string name will always be a
>substring of the sub name and in the same place in the name. a hash
>allows freedom to map different names to subs.
Yes, but in this case the addition flexibility does not appear to be
required. So you would be paying a programming and maintenance cost
for an unnecessary feature. This violates the rule that says that
everything should be as simple as possible.
>a dispatch table allows this to work under use strict
That is not a benefit. 'use strict refs' is only a means to an end,
to avoid certain types of reference *errors*. Those errors are not
relevant here. To argue that symbolic references are bad *because*
they result in 'strict' failures is circular reasoning.
At best, your argument shows that 'strict refs' may be defective,
because it may impede this entirely non-erroneous use of symbolic
references.
>i believe it will untaint a sub name too.
Fortunately for you, this argument is irrelevant, since the subroutine
names are all compile-time constants and are hence untainted.
If this argument were not irrelevant, you would be arguing against
your own position, Tainting is a security mechanism. If the
subroutine names had come from outside, they should *not* be
Read the rest of this message... (21 more lines)
>>>>> "MJD" == Mark Jason Dominus <mjd@plover.com> writes:
>> what if some random string was passed in from the outside
MJD> That is evidently not the case here. The four strings were
MJD> hardwired into a compile-time list constant.
the specific case here may show hardwired sub names. but that is rarely
the case and the problem could be solved with multiple methods. showing
a symref solution which may be ok here will potentially influence others
to use it where it is dangerous. that is a prime reason never to show
any symref solutions, especially here where there are many newbie eyes.
MJD> I do not see the purpose of checking members of a compile-time
MJD> list against the keys of a compile-time hash for verification.
MJD> If you don't trust the list, why would you trust the hash? Why
MJD> wouldn't you check the hash keys against a second hash, just to
MJD> be double sure?
the dispatch table is a also style to protect against potential
changes in the future as well. the OP never said that the list of sub
was fixed or would be permanently hardwired. i prefer to make the
assumption the code will change as we all know code does change.
MJD> Yes, but in this case the addition flexibility does not appear to
MJD> be required. So you would be paying a programming and
MJD> maintenance cost for an unnecessary feature. This violates the
MJD> rule that says that everything should be as simple as possible.
or as simple as possible for a reasonable amount of safety and
flexibility. applying the simple as possible rule only leads to no
strict as who needs the clutter of declarations?
>> a dispatch table allows this to work under use strict
MJD> That is not a benefit. 'use strict refs' is only a means to an
MJD> end, to avoid certain types of reference *errors*. Those errors
MJD> are not relevant here. To argue that symbolic references are bad
MJD> *because* they result in 'strict' failures is circular reasoning.
that may be correct, but it is a useful way to discuss it with
newbies. we emphasize use strict to eliminate the newbie use of
symrefs. but that always isn't clear so saying that that solution won't
run under strict refs can be easier to understand.
MJD> At best, your argument shows that 'strict refs' may be defective,
MJD> because it may impede this entirely non-erroneous use of symbolic
MJD> references.
Read the rest of this message... (34 more lines)
Next 6
Jump to [ End of thread ]
©2003 Google