Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

using a variable in a subroutine name

22 views
Skip to first unread message

Kristina Clair

unread,
Nov 6, 2001, 12:36:09 PM11/6/01
to
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

Jeff Zucker

unread,
Nov 6, 2001, 1:30:00 PM11/6/01
to
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

Ron Hartikka

unread,
Nov 6, 2001, 1:36:59 PM11/6/01
to
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" <kcl...@soya.serve.com> wrote in message
news:9s9747$r...@netaxs.com...

Uri Guttman

unread,
Nov 6, 2001, 1:36:58 PM11/6/01
to
>>>>> "JZ" == Jeff Zucker <je...@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 ------ u...@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

Jeff Zucker

unread,
Nov 6, 2001, 1:41:00 PM11/6/01
to
Uri Guttman wrote:
>
> >>>>> "JZ" == Jeff Zucker <je...@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

Michael Carman

unread,
Nov 6, 2001, 1:48:36 PM11/6/01
to
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

Mark Jason Dominus

unread,
Nov 6, 2001, 3:49:15 PM11/6/01
to
In article <3BE83084...@home.com>,

Michael Carman <mjca...@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

Uri Guttman

unread,
Nov 6, 2001, 5:21:26 PM11/6/01
to
>>>>> "MJD" == Mark Jason Dominus <m...@plover.com> writes:

MJD> In article <3BE83084...@home.com>,


MJD> Michael Carman <mjca...@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?

Michael Carman

unread,
Nov 6, 2001, 5:41:47 PM11/6/01
to
Mark Jason Dominus wrote:
>
> In article <3BE83084...@home.com>,
> Michael Carman <mjca...@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?

I'm not sure how to take that, Mark. Are you implying that
a) I should have gone into more detail, as you do in
http://perl.plover.com/varvarname.html
b) I should have said that it won't work under 'use strict',
which all non-trivial programs should have.
c) You don't think that symrefs are a bad thing when used to
call subroutines?

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

Fair enough. I don't think the hash is necessary, either. My first
thought was to put the subrefs directly into the loop:

foreach my $x (\&_send_email_zip, \&_send_email_txt,
\&_send_cp_txt, \&_send_cp_txt) {
# ...
}

but I felt that that might be unclear to the OP and that using a hash as
a dispatch table might be more easier to understand.

-mjc

Mark Jason Dominus

unread,
Nov 7, 2001, 11:38:25 AM11/7/01
to
In article <x74ro7v...@home.sysarch.com>,

Uri Guttman <u...@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
automatically untainted, because that would be unsafe. Disabling a
security mechanism is not a benefit.

>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

That is a non-reason. "It causes problems" is just FUD unless you can
identify a real problem that is caused. So far you have not done so.

>are those enough reasons?

Zero reasons is not enough, no.

Mark Jason Dominus

unread,
Nov 7, 2001, 12:04:12 PM11/7/01
to
In article <3BE8672B...@home.com>,
Michael Carman <mjca...@home.com> wrote:
>Dominus:

>> What's the problem?
>
>I'm not sure how to take that, Mark. Are you implying that

Not really any of those three things. I really did mean it just the
way I said: Simply that I didn't see what the problem was, and I
wanted to know what your objection was.

> a) I should have gone into more detail, as you do in
> http://perl.plover.com/varvarname.html

I think a close examination of that series of articles will show that
none of the reasons presented apply to this situation. (I might be
wrong, of course, in which case I would be grateful if you would point
it out.)

> b) I should have said that it won't work under 'use strict',
> which all non-trivial programs should have.

If you take as an article of absolute doctrine that "all non-trivial
programs should work under 'use strict'", then yes, I see that there
is a problem. But it would seem to me that the problem was in the
doctrine, not the code. It seems like putting the cart before the
horse.

'strict' can only be taken as an indication of likely errors. But the
computer does not understand the code, and we should not allow a
mechanical diagnosis to interfere with our ability to do a more
reasoned and substantive analysis. While it is true that *many* uses
of symbolic references are erroneous, and this is what occasions
'strict refs' in the first place, it is certainly not true that *all*
uses are erroneous. Avoiding a certain programming practice *just*
because it causes a 'strict refs' failure may be the most convenient
way to proceed, but we should view this as a pragmatic decision akin
to the one we make when we decide to complicate some code just work
around a compiler bug. In particular, we shouldn't make a virtue out
of such a practice; we should recognize it for what they it is: a
workaround, and we should consider the possibility that there might be
a way to improve 'strict refs' so that it does not emit warnings for
non-erroneous cases, and so that the workaround is not necessary in
the future.

> c) You don't think that symrefs are a bad thing when used to
> call subroutines?

If you had asked me yesterday, I might have said so, but consideration
of this particular example has forced me to examine that conclusion
more critically. Since I cannot see any problem in this case, it now
appears that there are some circumstances under which nothing is wrong
with using symrefs to call subroutines. (Or else I have missed
something, but if so, nobody has pointed it out to me yet.)

Maybe it will turn out that this is an isolated and unusual case, so
not worth the trouble to remember as an exception. But perhaps it
will turn out that this is a member of a large, common, and
easily-identified class of examples. Then my understanding of
programming practice will be improved by understanding how to identify
when I am in this class of situations.

I am just trying to understand the issue better. It was this same
process that led me to write the 'varvarname' articles in the first
place.

>Fair enough. I don't think the hash is necessary, either. My first
>thought was to put the subrefs directly into the loop:
>
> foreach my $x (\&_send_email_zip, \&_send_email_txt,
> \&_send_cp_txt, \&_send_cp_txt) {
> # ...
> }

That seems to me like a more direct way to solve the problem.

Now I wonder if perhaps that same solution will apply to all the
examples like this one? If I understood the issue better, and the
boundaries of the class of examples, I might be able to decide.

>but I felt that that might be unclear to the OP and that using a hash as
>a dispatch table might be more easier to understand.

I'd be interested to hear why you thought so. (Please take this
remark at face value.)

Uri Guttman

unread,
Nov 7, 2001, 12:41:43 PM11/7/01
to
>>>>> "MJD" == Mark Jason Dominus <m...@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.

i think it is an erroneous use of symrefs. there is no compelling reason
to use symrefs here so they shouldn't be used. symrefs should be used
when there is no other reasonable solution. a dispatch table is a very
reasonable solution here.

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

MJD> That is a non-reason. "It causes problems" is just FUD unless you can
MJD> identify a real problem that is caused. So far you have not done so.

MJD> Zero reasons is not enough, no.

then we disagree. i reiterate what i have said before, unless you know
when not to use symrefs, you should not use them. they are not needed
for basic stuff like sub dispatching. sure they work and sure the
newbies who ask for a way to create variables by name can use them as
well. discouraging its use for simple stuff is worthy in and of
itself. that is one reason there. allowing for flexibilty in the future
by having the keys not always match the sub names or controlling which
keys can call which subs are two more reasons for dispatch
tables. assuming hardwired sub names and keys is very limiting and
potentially dangerous. also it leads newbie to think that symrefs are ok
which is bad in general.

Uri Guttman

unread,
Nov 7, 2001, 12:53:17 PM11/7/01
to
>>>>> "MJD" == Mark Jason Dominus <m...@plover.com> writes:

>> c) You don't think that symrefs are a bad thing when used to
>> call subroutines?

MJD> If you had asked me yesterday, I might have said so, but
MJD> consideration of this particular example has forced me to examine
MJD> that conclusion more critically. Since I cannot see any problem
MJD> in this case, it now appears that there are some circumstances
MJD> under which nothing is wrong with using symrefs to call
MJD> subroutines. (Or else I have missed something, but if so, nobody
MJD> has pointed it out to me yet.)

see my other post for my take on this.

MJD> Maybe it will turn out that this is an isolated and unusual case,
MJD> so not worth the trouble to remember as an exception. But
MJD> perhaps it will turn out that this is a member of a large,
MJD> common, and easily-identified class of examples. Then my
MJD> understanding of programming practice will be improved by
MJD> understanding how to identify when I am in this class of
MJD> situations.

i think the situation is very clear in this case. there is no major
advantage to symrefs here and using them for a simple sub dispatch can
lead to problems later. why allow this path to danger at all? there is
no way someone will guarantee the keys and subs will never change or be
driven from outside data. so it is prudent to force checking via a
dispatch table.

MJD> I am just trying to understand the issue better. It was this
MJD> same process that led me to write the 'varvarname' articles in
MJD> the first place.

i agree with varvar and i think this falls under the same umbrella. the
fact that the key names seem to be fixed in relationship to the sub
names is no different than someone reading a line of var names and
symreffing them into existance. they can also claim (as i have seen
done) that they KNOW the names and won't use those var names elsewhere
or change them. and we KNOW that is not the case in the larger scheme of
programming. code always changes and mostly not by the author. so
leaving a supposedly safe use of symrefs for sub calls around is waiting
for someone to do the wrong thing later. that must be avoided in good
programming practice.

>> Fair enough. I don't think the hash is necessary, either. My first
>> thought was to put the subrefs directly into the loop:
>>
>> foreach my $x (\&_send_email_zip, \&_send_email_txt,
>> \&_send_cp_txt, \&_send_cp_txt) {
>> # ...
>> }

MJD> That seems to me like a more direct way to solve the problem.

for a simple fixed loop over a set of subs, that is a fine solution. but
what if they want to change it to a list to be called that is passed in?
then all the callers would have to know the full reference to each
sub. and if you wanted to move or rename a sub to another package? then
you would have to find all the sub refs and clean them up. a key to the
sub and a dispatch table is much cleaner there. so why not do that from
the beginning? the loop is fine for now and solve the symref problem but
teaching about dispatch tables is a good idea here and is not a bad
solution as it provides for easier extensions and better control in the
future.

>> but I felt that that might be unclear to the OP and that using a hash as
>> a dispatch table might be more easier to understand.

MJD> I'd be interested to hear why you thought so. (Please take this
MJD> remark at face value.)

i have explained my reasons for dispatch tables. i hope you take them at
face value too. i feel they are the proper solution for most indirect
sub call problems.

Mark Jason Dominus

unread,
Nov 7, 2001, 1:40:10 PM11/7/01
to
In article <x7ofmet...@home.sysarch.com>,

Uri Guttman <u...@stemsystems.com> wrote:
>>>>>> "MJD" == Mark Jason Dominus <m...@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.

I'm not sure what your point is here. So what if it's rarely the
case? All programming problems are 'rarely the case'. You have to
program for the problem you have, not some other problem that someone
on another continent is trying to solve.

I asked you for drawbacks of the symbolic references technique for
this example because this example was the one you were addressing. As
you yourself pointed out, I'm well aware of the drawbacks of symbolic
references in general and have written several widely-read articles on
the subject.

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

I think that's a crappy philosophy. We should encourage better
understanding of real problems, not superstitious avoidance of certain
techniques.

This was one of my major complaints about the 'Perl for Dummies' book.
The author didn't have a good understanding of Perls string-to-number
conversions, so he warned the beginners to stay away from that part of
Perl:

You can do ``numberish'' things to strings, but the results
are almost impossible to predict accurately...Perl tries hard
to find numbers in the strings and do the ``right thing'' with
them, but you cannot always guess what that ``right thing''
is. Don't risk it: Always use math functions and operators
just for numbers. (p.93)

You're doing exactly the same thing here: You, want to tell everyone
else to stay away from symbolic references, and to give up on trying
to understand the real costs and benefits. In fact, what you're doing
is worse than what the author of _Perl for Dummies_ does, because
you're saying that nobody else should even discuss these dangerous and
forbidden topics in public.

It's okay with me if you want to be a Dummy yourself, but please don't
force it on the rest of us.

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

With your solution, if the list changes, you then have to change the
dispatch table. This is an additional maintenance cost. With the
symbolic reference solution, no additional maintenance is required,
and the change needs to be made in only one place.

This the symbolic reference solution is better suited to the situation
where the code will change, in at least this one way.

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

Yes. But you have not yet demonstrated that your method introduces
*any* additional flexibility or safety.

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

I strongly contest the assertion that illogical arguments and circular
reasoning are a useful way of discussing anything with anyone.

I think we may have a fundamential philisophical difference here. I
would like the newbies to become more empowered and to learn to
recognize the real costs and benefits of symbolic references, whatever
they are.

>i think it is an erroneous use of symrefs. there is no compelling
>reason to use symrefs here so they shouldn't be used. symrefs should
>be used when there is no other reasonable solution.

That is also a circular argument. From the assumption that "symrefs
should [only] be used when there is no other reasonable solution", it
is very easy to conlude that all uses of symrefs are erroneous. What
you have not done is given any reason for your assumption other than
simple assertion.

The code the original poster presented has discernible advantages over
your dispatch table solution, as I've pointed out. You have not
presented any disadvantages that do not depend on your own unfounded
assertion that all uses of symrefs are defective.

> MJD> Zero reasons is not enough, no.
>
>then we disagree.

I am interested, but not surpised, to see that you consider zero
reasons to be enough to prove your point.

Michael Carman

unread,
Nov 7, 2001, 2:37:54 PM11/7/01
to
Mark Jason Dominus wrote:
>
> In article <3BE8672B...@home.com>,
> Michael Carman <mjca...@home.com> wrote:
>
> >Dominus:
> > >
> > > What's the problem?
> >
> > a) I should have gone into more detail, as you do in
> > http://perl.plover.com/varvarname.html
>
> I think a close examination of that series of articles will show that
> none of the reasons presented apply to this situation. (I might be
> wrong, of course, in which case I would be grateful if you would point
> it out.)

There isn't. I had skimmed through them before posting, just to be
refresh my memory, and saw nothing about this situation. Even so I find
them applicable in a general sense.

> > b) I should have said that it won't work under 'use strict',
> > which all non-trivial programs should have.
>
> If you take as an article of absolute doctrine that "all non-trivial
> programs should work under 'use strict'", then yes, I see that there
> is a problem. But it would seem to me that the problem was in the
> doctrine, not the code.

Understandable, but even if there's nothing harmful in using a symref in
this situation, there's no compelling reason to do so, either. I think
that the doctrine is sound:

1) In general, symrefs are bad and dangerous.
2) 'strict refs' stops you from using symrefs; ergo it's good.
All non-trivial programs should use it.
3) If you can't do something under 'strict refs', you probably
shouldn't be doing it anyway. Look for a better way.
4) If you know why using symrefs is good/necessary for a
particular situation, go ahead and disable 'strict refs'
locally.

Any time I find myself operating in (4), I feel vaguely dirty. ;)

You seem interested in the philosophy behind the use/avoidance of
symrefs. I think that's an admirable pursuit. For my part, I'm less
philosophical and more pragmatic.



> >My first thought was to put the subrefs directly into the loop:
> >
> > foreach my $x (\&_send_email_zip, \&_send_email_txt,
> > \&_send_cp_txt, \&_send_cp_txt) {
> > # ...
> > }
>

> [...]


>
> >but I felt that that might be unclear to the OP and that using
> >a hash as a dispatch table might be more easier to understand.

^^^^^^^^^^^
Yikes! I have lousy grammar. :O

> I'd be interested to hear why you thought so.

It was a feeling, mostly, and as such not necessarily logical. :)

Something in the back of my mind said that a beginning programmer (who
is used to looping over strings and numbers) might be shocked at the
thought of looping over code references. Using the dispatch table seemed
like a good way to break the problem into smaller and simpler chunks.

I could be wrong of course; maybe the shorter solution is the clearer
one, even to novices.

-mjc

Michael Carman

unread,
Nov 7, 2001, 3:42:43 PM11/7/01
to
Mark Jason Dominus wrote:
>
> In article <x7ofmet...@home.sysarch.com>,
> Uri Guttman <u...@stemsystems.com> wrote:
> >
> > the specific case here may show hardwired sub names. but that
> > is rarely the case and the problem could be solved with multiple
> > methods.
>
> I'm not sure what your point is here. So what if it's rarely the
> case? All programming problems are 'rarely the case'. You have to
> program for the problem you have, not some other problem that someone
> on another continent is trying to solve.

If this question had been asked and answered in private correspondance,
I would agree, but this is a public forum.

Long before I ever started posting here, I lurked. I didn't have any
particular questions, but I was a Perl novice and was interested in
learning more. (I didn't even know about -w, use strict, or perldoc.
Those three things were probably the most valuable of everything I've
learned here.) So I followed threads that I found interesting, tried to
glean some useful information from them, and then tried to apply that
newfound knowledge to the tasks I had.

If I had read a thread with a symref question and a symref answer, I
might have thought to myself "Wow! I can do all sorts of cool stuff with
that!" I shudder to think what sort of atrocities I might have created
with that little bit of dangerous knowledge. I had a hard enough time
making my early forays into Perl -w and 'strict' clean.

So while I agree that the main focus of any thread should be answering
the specific question asked, I also feel that we must consider the
larger picture. Some people treat this newsgroup as a helpdesk, others
as a classroom.

> >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.
>
> I think that's a crappy philosophy. We should encourage better
> understanding of real problems, not superstitious avoidance of certain
> techniques.

Well, it's easier to tell a newbie to never use symrefs and let them
learn of the exceptions later than to throw it all at them at once. Of
course, then you're doing a disservice to the mid-level programmers who
are ready to learn about those exceptions.

Ideally those of use who respond to questions would always give accurate
and *full* answers, but that just doesn't happen. We get tired, or we
want to help but don't have time to present the whole picture so we omit
the finer points.

I think we have a tendancy to assume that anyone asking a symref
question doesn't know enough Perl to be using them yet. Answering that
question is kind of like giving someone a driver's license without
making them take the test first.

-mjc

0 new messages