Messages 1-10 from thread
Next 6
Jump to [ End of thread ]

Message 1 in thread
From: Kristina Clair (kclair@soya.serve.com)
Subject: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 09:37:19 PST
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
Message 2 in thread
From: Jeff Zucker (jeff@vpservices.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 10:33:50 PST
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
Message 3 in thread
From: Uri Guttman (uri@stemsystems.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 10:37:51 PST
>>>>> "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
Message 4 in thread
From: Jeff Zucker (jeff@vpservices.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 10:44:51 PST
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
Message 5 in thread
From: Ron Hartikka (ronh@iainc.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 10:35:51 PST
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)

Message 6 in thread
From: Michael Carman (mjcarman@home.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 11:37:44 PST

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
Message 7 in thread
From: Mark Jason Dominus (mjd@plover.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 12:49:16 PST
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
Message 8 in thread
From: Uri Guttman (uri@stemsystems.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-06 14:22:18 PST
>>>>> "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
Message 9 in thread
From: Mark Jason Dominus (mjd@plover.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-07 08:38:26 PST
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)

Message 10 in thread
From: Uri Guttman (uri@stemsystems.com)
Subject: Re: using a variable in a subroutine name
 
View this article only
Newsgroups: comp.lang.perl.misc
Date: 2001-11-07 09:42:36 PST

>>>>> "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