[19890] in Perl-Users-Digest
Perl-Users Digest, Issue: 2085 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Nov 7 14:15:50 2001
Date: Wed, 7 Nov 2001 11:15:18 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <1005160518-v10-i2085@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Wed, 7 Nov 2001 Volume: 10 Number: 2085
Today's topics:
Re: using a variable in a subroutine name (Mark Jason Dominus)
Re: using a variable in a subroutine name (Mark Jason Dominus)
Re: using a variable in a subroutine name <uri@stemsystems.com>
Re: using a variable in a subroutine name <uri@stemsystems.com>
Re: using a variable in a subroutine name (Mark Jason Dominus)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Wed, 07 Nov 2001 16:38:25 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: using a variable in a subroutine name
Message-Id: <3be96381.6764$307@news.op.net>
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
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.
--
@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
------------------------------
Date: Wed, 07 Nov 2001 17:04:12 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: using a variable in a subroutine name
Message-Id: <3be9698b.6838$28b@news.op.net>
In article <3BE8672B.1D651035@home.com>,
Michael Carman <mjcarman@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.)
--
@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
------------------------------
Date: Wed, 07 Nov 2001 17:41:43 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: using a variable in a subroutine name
Message-Id: <x7ofmetr3p.fsf@home.sysarch.com>
>>>>> "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.
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
--
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
------------------------------
Date: Wed, 07 Nov 2001 17:53:17 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: using a variable in a subroutine name
Message-Id: <x7lmhitqkf.fsf@home.sysarch.com>
>>>>> "MJD" == Mark Jason Dominus <mjd@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.
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
------------------------------
Date: Wed, 07 Nov 2001 18:40:10 GMT
From: mjd@plover.com (Mark Jason Dominus)
Subject: Re: using a variable in a subroutine name
Message-Id: <3be98009.6bb4$1d5@news.op.net>
In article <x7ofmetr3p.fsf@home.sysarch.com>,
Uri Guttman <uri@stemsystems.com> wrote:
>>>>>> "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.
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.
--
@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
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 2085
***************************************