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

Abstraction

1 view
Skip to first unread message

Venkataraman Chandrasekhar

unread,
Mar 11, 1994, 2:44:59 PM3/11/94
to

Let me list a subroutine, provide a description, and then ask a
question

sub delete_file {
local($filename) = @_;

$cmdline = "rm -rf $filename";
$output = `$cmdline 2>&1 `;
if ($?) {
$warning = "\n Problems deleting file $filename" .
"\n Command Used: $cmdline" .
"\n Output Received: $output";

printf "\n $warning";

$status = 'ERROR';
}
else {
$status = 'GOOD';
}
return ($status);
}

The above is in Perl. Unix provides 'rm' to remove files, which can be
used in Perl under backticks. The subroutine above adds a small amount
of functionality to 'rm' by:

. Providing error handling

. Being more English like and less programmerese
(delete_file versus rm)

I prefer to make subroutines like the above and use them instead of
using 'rm' for instance and performing error handling in place.
Usually the subroutines add a little more functionality than the above
and in that sense the above is an extreme case. In our system, we use
'core commands' from another package and I prefer to convert the
cryptic core commands into more English like subroutines. Further, if
it seems that a likely to be useful higher level function may be built
by combining say two or three lower level functions, I do so even if I
don't have an immediate use for it. The idea is to make building
blocks from the ground up thus enriching the set of building blocks
that came as a part of the language. (One author calls the latter
factory objects.)

Some people dislike this practice. The objection usually voiced is
that extra time is spent in branching to the subroutine and back. Our
set of programs is interpreted (as opposed to compiled). The
application is also 'processing user entries'; the extra time
branching is not a factor at all. I contend that in all but
exceptional cases the advantages of the practice (reuse, english
likeness, lack of clutter in the calling programs) make it preferable.

Some people seem to be bothered by the adding of more and more units
and claim that there is more to maintain. If the lines of code were in
place instead of in a subroutine they still need to be maintained.

Any comments ?

Jonas Nilsson

unread,
Mar 12, 1994, 8:05:31 PM3/12/94
to
In article <1994Mar11.1...@kocrsv01.delcoelect.com> c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
[...]

'core commands' from another package and I prefer to convert the

^^^^^^^^^^^^^

Eh?? I guess you mean that it's like very basic commands or
something...

Ok, the comments now:

Commentary on "slower commands":

I don't see anything that could interfer with other users (read: those
who dislike these "improved" programs). I mean, you can put your
programs in one directory, and they can remove that directory from
their searchpath.

Commentary on "more userfriendly":

I myself do not care too much about how userfriendly commands are, as
long as you can modify them to your liking. With that I mean that I
would probably not use your programs if they didn't made them more
powerful. Perl programs are often written to be system commands
(improved or extended core commands) but you say that you write them
to make them more userfriendly (only?).

Conclusion: If you want to convince your opponents, make the commands
more powerful. Listen to what they want, instead of trying to
convince them to want something that they didn't want in the first
place.

Just my opinion.
--
Jonas Nilsson | Internet: di9...@pt.hk-r.se | "Talk as much as |
Tranbärsvägen 23 | Phone: +46-(0)457-27942 | you want about |
S-372 38 Ronneby | Phone home: +46-(0)8-56032348 | cutting edge |
+46-(0)457-27942 +-------------------------------+ technology, but |
Sweden | someone's got to hold the knife." -- Snake eyes |

Larry Wall

unread,
Mar 13, 1994, 8:47:18 PM3/13/94
to
In article <1994Mar11.1...@kocrsv01.delcoelect.com> c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
: Any comments ?

Sure. You're going to be surprised the first time someone passes in a
filename containing shell metacharacters, and then you're going to be
even more surprised if that filename contains the printf metacharacter.

I have no problem with people who want to roll their own user
interface--I am not a monoculturalist. However, if you're going to be
designing user interfaces, you need to hold yourself to a higher standard
of robustness. To put it as bluntly as possible, I don't want to hear
people maligning Perl because your code deleted the root filesystem.

I did have one quibble with your user interface. I think it's a
disimprovement to return a "true" string for both success and failure.
You're going to have people writing:

if (&delete_file($file))

or worse,

if (&delete_file($file) == "GOOD")

which is always bad. Note the use of == where eq is needed. A good human
interface makes allowances for human nature.

Larry

P.S. Speaking of user interfaces, you really oughta learn how to cross-post
too. Grumble...

Antonio Vasconcelos

unread,
Mar 15, 1994, 6:57:31 PM3/15/94
to
c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
: Some people seem to be bothered by the adding of more and more units

: and claim that there is more to maintain. If the lines of code were in
: place instead of in a subroutine they still need to be maintained.

Well, you have to recognize that this is a very strong point.
No problem if one are talking about 5, or 10 of this routines, but
what if you have 100's of them ?
I don't think that turning some code more verbose helps someone
writing better programs.
Every time I see this idea I have to comment that COBOL is one of the
major plages of computer programming...

The only exception that I can remember are the C #define macros and
the macros of some Macro Assemblers, where your verbose code is turned
into 'normal' code in the pre-processing fase.
But Perl don't have macros. So, verbosity could be a no-no.

In the case you talk about, the sub is not usefull, first, because you
don't have to use `rm ...`, the Perl unlink() will do, 2nd, because
you didn't add any usefulness to the command. It just delete the file
and returns a status witch is worst than something like:

if(!(&delete_file(fname)))
{
...ERROR...
}

delete_file() whould be usefull if it does something that rm/unlink
doesn't do, like save a copy of the file for an possible undelete or
do aditional security checking.

Just my 2 cents...
--
regards,

Antonio Vasconcelos
@ The Lisbon $tock Exchange (BVL) require 'std/disclaimer.ph'

<<< Computers also eliminate spare time. >>>

Venkataraman Chandrasekhar

unread,
Mar 16, 1994, 10:30:43 AM3/16/94
to

Frankly, I am surprised by the tone of mild hostility in the followup.
My whole point of posting on this topic is to get the opinions of
those outside our group, whether they are supportive or not. There is
the danger that the opinions are given based on the very limited
information that I have given (i.e., without having had a chance to
look at the rest of our system).

I guess that I got into this habit of building slightly more functional
building blocks (when compared to the building blocks provided by the
language) and reusing them from my limited but enjoyable experience with
Smalltalk. I have no problem agreeing to good standards of robustness
etc. I don't stop with the first level building blocks but go on to
higher levels. I see these as customization to our local site based on
our functions. The example I posted was not typical in this sense. (A
couple of people pointed out that I could use Perl's unlink.) Some of
these functions may be used by other Perl users also, laying aside for
a minute the question of whether these are better or not.

For instance, I often have a need to:

1. create a temporary directory
2. perform certain functions here
3. delete the temporary directory
4. return to the original directory

I have subroutines to do 1, 3, and 4. I use them instead of repeating
the lines in the subroutines, each place it is called. I see it as an
improvment. a given function is done only in one place (in the
subroutine); the subroutines are more English-like and less
computerese.

Now on to specifics:

>
>Sure. You're going to be surprised the first time someone passes in a
>filename containing shell metacharacters, and then you're going to be
>even more surprised if that filename contains the printf metacharacter.
>

In case you care to educate me, what will happen ? You can point to pages
in the Camel book.

>I have no problem with people who want to roll their own user
>interface--I am not a monoculturalist. However, if you're going to be
>designing user interfaces, you need to hold yourself to a higher standard
>of robustness. To put it as bluntly as possible, I don't want to hear
>people maligning Perl because your code deleted the root filesystem.
>

The building blocks that I construct are strictly for my own use. I
have a set of standards that continue to evolve on their usage. If
others want to use them, they should follow these standards. I have no
problem building in allowances for human nature, as you say.

How can my 'code delete the root filesystem' and consequently
'people maligning Perl' ? Aren't the files of the root filesystem
protected by permissions ?

>I did have one quibble with your user interface. I think it's a
>disimprovement to return a "true" string for both success and failure.
>You're going to have people writing:
>
> if (&delete_file($file))
>
>or worse,
>
> if (&delete_file($file) == "GOOD")
>
>which is always bad. Note the use of == where eq is needed. A good human
>interface makes allowances for human nature.
>

1. The convention and examples here (in our organization) also clearly ask
for the use of 'eq' and not '=='.

2. My convention and examples here also require testing specifically
for 'GOOD' and 'ERROR'. I personally never write

if (&delete_file($file))

(because deleting being true does not mean quite the same thing as
delete being successful, to me). More importantly, almost all my
subroutines return several variables back, the first of which is
always the status; the rest are meaningful only if status eq 'GOOD'.

An example of something in progress:

local($debug_mode) = 'TRUE';
local($calds_version) = "6.1";

local(
$status,
$original_directory_name,
$temporary_directory_name,
$library_name,
$library_name_in_full,
) = &setup($debug_mode,
$calds_version);
if ($status ne 'GOOD') { exit };
print DEBUG "\n Original Directory: $original_directory_name";
print DEBUG "\n Temporary Directory: $temporary_directory_name";
print DEBUG "\n Library Name: $library_name";
print DEBUG "\n Library Name In Full: $library_name_in_full";

# process input - get sw member name - check that members are readable
# they both point to same sw member etc.

local (
$status,
$software_member_name,
$bundle1,
$DLS1,
$bundle2,
$DLS2,
@list_of_calsets_to_be_compared
) = &process_user_input();
print DEBUG "$status\n";
if ($status ne 'GOOD') {
$status = &cleanup(
$original_directory_name,
$temporary_directory_name,
$library_name_in_full,
);
exit;
}
print DEBUG "
Bundle 1: $bundle1
DLS 1: $DLS1
Bundle 2: $bundle2
DLS 2: $DLS2
Name of software member in the bundles being compared:
$software_member_name
Calsets to be compared:
@list_of_calsets_to_be_compared";


Followup-To:
References: <1994Mar11.1...@kocrsv01.delcoelect.com> <1994Mar14....@netlabs.com>
From: c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar)
Organization: Delco Electronics Corp.
Subject: Re: Abstraction
Keywords:

Tom Christiansen

unread,
Mar 17, 1994, 11:16:59 AM3/17/94
to
:-> In comp.lang.perl, c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
:>I did have one quibble with your user interface. I think it's a

:>disimprovement to return a "true" string for both success and failure.
:>You're going to have people writing:
:>
:> if (&delete_file($file))
:>
:>or worse,
:>
:> if (&delete_file($file) == "GOOD")
:>
:>which is always bad. Note the use of == where eq is needed. A good human
:>interface makes allowances for human nature.
:>
:
:1. The convention and examples here (in our organization) also clearly ask
:for the use of 'eq' and not '=='.
:
:2. My convention and examples here also require testing specifically
:for 'GOOD' and 'ERROR'. I personally never write
:
: if (&delete_file($file))
:
:(because deleting being true does not mean quite the same thing as
:delete being successful, to me). More importantly, almost all my
:subroutines return several variables back, the first of which is
:always the status; the rest are meaningful only if status eq 'GOOD'.

Having things that work return true and things that fail return
false is simple, intuitive, and powerful.

You are free, of course, to adopt any call interface you choose, but
don't expect it to be beloved by all those around you. For example,
you might do something like this:

STATUS: for ( &delete_file($file) ) {
/^ERROR: (.*)/ && do {
warn "delete error: $1\n";
last STATUS;
};

/^GOOD: (.*)/ && do {
if ($DEBUG) {
warn qq(file "$file" deleted\n);
}
last STATUS;
};

die qq{unknown return code from delete_file("$_"): $_};
}


But that's just not what people are used to doing. It seems
easier and clearer to do this:

&delete_file($file) || warn qq{delete_file("$file"): $!};

Or, if you would prefer,

if (! &delete_file($file)) {
warn qq{delete_file("$file"): $!};
}

One point to ponder is whether you want multiple success states
or multiple failure states. Calling a subprocess has one success
state (child exits 0) and multiple failure ones (any non-zero return
code). Making a system call has multiple success conditions (how
many bytes DID you read? what IS my pid?), and just one failure
condition. That way you can always say

function || die;

But in the case of wanting to know WHY it failed, we have to multiplex it
through another mechanism. For program status, you get back multiple
significant bytes of information, with signal and coredump information
nestled in there. For system calls, you need the auxiliary mechanism of
errno, which is of course $! in perl.

--tom
--
Tom Christiansen tch...@cs.colorado.edu
"Will Hack Perl for Fine Food and Fun"
Boulder Colorado 303-444-3212

Larry Wall

unread,
Mar 17, 1994, 12:36:49 PM3/17/94
to
In article <1994Mar16.1...@kocrsv01.delcoelect.com> c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
: Frankly, I am surprised by the tone of mild hostility in the followup.

I guess I was in a bad mood. I didn't think I let it show THAT much though.

It did look as though you were expecting to get a negative reaction to
your remarks, so I figured I'd oblige you. I just didn't happen to
want to talk about the things you wanted to talk about... :-)

: My whole point of posting on this topic is to get the opinions of


: those outside our group, whether they are supportive or not. There is
: the danger that the opinions are given based on the very limited
: information that I have given (i.e., without having had a chance to
: look at the rest of our system).
:
: I guess that I got into this habit of building slightly more functional
: building blocks (when compared to the building blocks provided by the
: language) and reusing them from my limited but enjoyable experience with
: Smalltalk. I have no problem agreeing to good standards of robustness
: etc. I don't stop with the first level building blocks but go on to
: higher levels. I see these as customization to our local site based on
: our functions. The example I posted was not typical in this sense. (A
: couple of people pointed out that I could use Perl's unlink.) Some of
: these functions may be used by other Perl users also, laying aside for
: a minute the question of whether these are better or not.
:
: For instance, I often have a need to:
:
: 1. create a temporary directory
: 2. perform certain functions here
: 3. delete the temporary directory
: 4. return to the original directory
:
: I have subroutines to do 1, 3, and 4. I use them instead of repeating
: the lines in the subroutines, each place it is called. I see it as an
: improvment. a given function is done only in one place (in the

: subroutine); teh subroutines are more English-like and less
: computerese.

I have no problem whatsoever with your building up your own interface.
In fact, I like the bottom-up approach. It's how I program.

: Now on to specifics:


:
: >Sure. You're going to be surprised the first time someone passes in a
: >filename containing shell metacharacters, and then you're going to be
: >even more surprised if that filename contains the printf metacharacter.
:
: In case you care to educate me, what will happen ? You can point to pages
: in the Camel book.

If someone gives your routine a filename of "foo;bar", it will end up
trying to execute "rm -rf foo;bar". You'd better hope that "bar" is a
benign command. If your filename contains a % character, the warnings
you're printing will try to use that as a printf metacharacter. (This
is a problem in C as well as Perl.) In general, instead of saying

printf $text

you should say

printf "%s", $text

or better, just

print $text;

: >I have no problem with people who want to roll their own user


: >interface--I am not a monoculturalist. However, if you're going to be
: >designing user interfaces, you need to hold yourself to a higher standard
: >of robustness. To put it as bluntly as possible, I don't want to hear
: >people maligning Perl because your code deleted the root filesystem.
: >
:
: The building blocks that I construct are strictly for my own use. I
: have a set of standards that continue to evolve on their usage. If
: others want to use them, they should follow these standards. I have no
: problem building in allowances for human nature, as you say.

You just contradicted yourself. Standards by their very nature are
requiring people to go against their nature. Otherwise they wouldn't
be necessary, no? You see many "Please stay off grass" signs because
people like to walk on grass. You don't see many "Please don't jump
out this window" signs because people don't naturally want to do that.
I guess I'm arguing that lawns are unnatural. I certainly don't mow
my lawn as often as the standards specify... :-)

I'm not against grass as a user interface, but we have to realize
there's a tradeoff.

: How can my 'code delete the root filesystem' and consequently

: 'people maligning Perl' ? Aren't the files of the root filesystem
: protected by permissions ?

If someone uses your routines in a setuid program, then it has the
permissions granted by the program. If the program belongs to root,
anybody could leave a booby-trap filename containing a newline to
get it to delete any file on the system.

Even when you're just using it for yourself, your routine will fail
if you run an application that happens to produce filenames with
spaces in them. This happens quite often when you start dealing with
data from Macs and Amigas, especially if you're mounting filesystems
under NFS.

: >I did have one quibble with your user interface. I think it's a


: >disimprovement to return a "true" string for both success and failure.
: >You're going to have people writing:
: >
: > if (&delete_file($file))
: >
: >or worse,
: >
: > if (&delete_file($file) == "GOOD")
: >
: >which is always bad. Note the use of == where eq is needed. A good human
: >interface makes allowances for human nature.
: >
:
: 1. The convention and examples here (in our organization) also clearly ask
: for the use of 'eq' and not '=='.

People, being people, will nonetheless type == when they mean eq a
goodly part of the time. I do it occasionally myself.

: 2. My convention and examples here also require testing specifically


: for 'GOOD' and 'ERROR'. I personally never write
:
: if (&delete_file($file))
:
: (because deleting being true does not mean quite the same thing as
: delete being successful, to me).

Perl itself doesn't make the distinction, so in some sense you're fighting
the mindset of the language here.

: More importantly, almost all my


: subroutines return several variables back, the first of which is
: always the status; the rest are meaningful only if status eq 'GOOD'.

The typical way I do that is by returning a null list, which when assigned
to a list of variables returns a boolean value of false. So typically I'd
say:

if ( ($foo, $bar, $baz) = &do_something() ) {
&process($foo,$bar,$baz);
}
else {
warn "Couldn't do something\n";
}

I'm not saying this is the only way to do it, but the language is
designed to make that easy.

Larry

Paul Phillips

unread,
Mar 17, 1994, 3:32:43 PM3/17/94
to
In article <1994Mar17.1...@netlabs.com> lw...@netlabs.com (Larry Wall) writes:
>I'm not against grass as a user interface, but we have to realize
>there's a tradeoff.

I've seen grass used as a user interface, and nobody gets any work
done. I think you should reconsider, Larry. :-)

|-------------------------------------------------------------------------|
| Paul Phillips | EMAIL: pa...@is.internic.net |
| InterNIC Information Services | WWW: http://www.internic.net/~paulp/ |
| Reference Desk Staff | PHONE: 619-455-4626 FAX: 619-455-4640 |
|-------------------------------------------------------------------------|

Roderick Schertler

unread,
Mar 18, 1994, 12:44:15 PM3/18/94
to
On Wed, 16 Mar 1994 15:30:43 GMT, c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) said:

> if ($status ne 'GOOD') { exit };

Careful, you just returned 0 to your caller, so she has no idea that
something went wrong. (Also, it's a great idea to get into the habit of
dying rather than exiting when there is an problem, for some day you'll
turn one of these scripts into a library, and some time after that
you'll want to trap and handle that error (and eval can be used to catch
exceptions raised by die, but exit is for keeps).)

-Roderick
--
Roderick Schertler
International Bonded Couriers/Miami
rode...@ibcinc.com

Venkataraman Chandrasekhar

unread,
Mar 18, 1994, 1:41:45 PM3/18/94
to

In article <1994Mar14....@netlabs.com>, lw...@netlabs.com (Larry Wall) writes:
> In article <1994Mar11.1...@kocrsv01.delcoelect.com> c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
> : Any comments ?
>
>
> I have no problem with people who want to roll their own user
> interface--I am not a monoculturalist. However, if you're going to be
> designing user interfaces, you need to hold yourself to a higher standard
> of robustness. To put it as bluntly as possible, I don't want to hear
> people maligning Perl because your code deleted the root filesystem.
>

A quick comment here. (I did receive an e-mail from Larry Wall in
response to my previous followup to this. I plan to respond to that
some time. One of Larry's points was: if a program which assumed
root permission via the setuid mechanism called my subroutine
delete_file all kinds of hell will break loose and Perl may me
maligned.)

I was not proposing my subroutine as an improvment over Perl's
unlink. (unlink is better; I was not aware of it when I wrote
delete_file - otherwise, I would have used unlink in it). In our
group, before I wrote delete_file, people have been using 'rm'
every time they needed to delete a file. So the real comparison
should be between 'rm' in place every time versus 'rm' in delete_file
(and not between delete_file and unlink, as Larry did). That being the
case, delete_file is not any worse than 'rm', as far as use in a
root setuid file is concerned.

Conclusion ? Randy Schwartz is nicer. (All he did was point out
in a polite e-mail to me that 'unlink' would work better.) :) :)

Chandrasekhar


Tom Christiansen

unread,
Mar 19, 1994, 11:58:22 AM3/19/94
to
:-> In comp.lang.perl, c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
:Conclusion ? Randy Schwartz is nicer. (All he did was point out
:in a polite e-mail to me that 'unlink' would work better.) :) :)

He's Randal (with just one el), not Randy. Well, he may be randy too,
but I don't think that should be open to net discussion. :-)

"By their postings shall ye know them." Sigh. How limited.

v2...@delphi.com

unread,
Mar 19, 1994, 4:58:05 PM3/19/94
to
Paul Phillips <pa...@is.internic.net> writes:

>I've seen grass used as a user interface, and nobody gets any work

This is from the original poster of this thread following up from his home
account. Somebody once asked a football player whther he liked grass or
artificial turf. Reply: I have never smoked artificial turf. :) Shaker

v2...@delphi.com

unread,
Mar 19, 1994, 4:59:56 PM3/19/94
to
Thanks for your constructive, helpful comments. I will update my `standards'
based on these. Shaker replying from home.

v2...@delphi.com

unread,
Mar 19, 1994, 5:05:43 PM3/19/94
to
Tom Christiansen <tch...@cs.Colorado.EDU> writes:

>:Conclusion ? Randy Schwartz is nicer. (All he did was point out

I showed my unfamiliarity with Western (European ? Anglo-Saxxon) names here. I
was too lazy to get teh Camel book out to get his exact name. Shaker (from
home).

Chaim Frenkel

unread,
Mar 20, 1994, 4:15:19 PM3/20/94
to
tch...@cs.Colorado.EDU (Tom Christiansen) declaims:

"By their postings shall ye know them." Sigh. How limited.

But if that's all you are limited to... :-)

<chaim>
--
Chaim Frenkel On contract at:
ch...@nlk.com ch...@fsrg.bear.com
Nonlinear Knowledge, Inc. Bear Stearns & Co., Inc.

Larry Wall

unread,
Mar 21, 1994, 2:45:46 PM3/21/94
to
In article <1994Mar18.1...@kocrsv01.delcoelect.com> c2...@kocrsv01.delcoelect.com (Venkataraman Chandrasekhar) writes:
: I was not proposing my subroutine as an improvment over Perl's

: unlink. (unlink is better; I was not aware of it when I wrote
: delete_file - otherwise, I would have used unlink in it). In our
: group, before I wrote delete_file, people have been using 'rm'
: every time they needed to delete a file. So the real comparison
: should be between 'rm' in place every time versus 'rm' in delete_file
: (and not between delete_file and unlink, as Larry did).

Er, if you go back and look, I said nothing about unlink. My point
was that your user interface, though well intended, could fail in
unexpected ways. I did not realize at the time that my message
was going to be an experiment in cross-cultural communication.
Unfortunately, while I intended to mostly communicate advice, it
appears that I mostly communicated offense. Sorry 'bout that.

: Conclusion ? Randy Schwartz is nicer. (All he did was point out

: in a polite e-mail to me that 'unlink' would work better.) :) :)

I agree that Randal is very nice. He certainly doesn't deserve the
treatment he's been getting lately.

On the other hand, I think that Randal and I would agree that being
"nice" is not necessarily the highest goal in life. Someone has to
report the bad news as well as the good. A good messenger has to
ignore the fact that he might get shot.

Randal can't talk about it, but I suspect this is what happened to him
at Intel. If so, Intel would be intelligent to drop the charges. But
I don't expect it. Witch hunts tend to gain more and more momentum
until they finally explode of their own incoherency.

Further reading: Matthew 5:3-16.

Larry

0 new messages