Re: Confusion in naming variables in subroutines
by liverpole (Monsignor) on Jan 24, 2007 at 01:14 UTC
|
In my opinion, it's perfectly fine to do it this way.
Although they are separate variables in memory, they contain the same values (ie. refer to the same measurements), so it makes perfect sense to name them the same. Besides which, the names are nice and descriptive, so having them named anything else would only be potentially confusing.
The important thing is, of course, that you've correctly used my to declare the lexical versions, scoped to the subroutine. To be even more safe, I'd recommend use strict; and use warnings; at the top of the program.
s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: Confusion in naming variables in subroutines
by ikegami (Patriarch) on Jan 24, 2007 at 04:50 UTC
|
For unrelated reasons*, I don't like working at the global level. This has the side-effect of avoiding the issue.
#!/usr/bin/perl -w
{
my ( $length, $breadth, $height ) = ( 10, 20, 30 );
my $volume = calc_volume( $length, $breadth, $height );
print "\nvolume = $volume\n";
}
sub calc_volume {
my ( $length, $breadth, $height ) = @_;
my $volume = $length * $breadth * $height;
return $volume;
}
While the snippet you provided has two variables with the same name in scope at the same time, the snippet I provided does not.
* — First, it makes the scope of variables much larger than it needs to be. Secondly, global objects are destroyed in an unpredictable order. That means a child object can be reaped before its owners is, which is bad if you have a custom destructor.
| [reply] [d/l] |
|
|
Ditto. I generally start all but the most trivial (and often even those) scripts something like:
#!/usr/bin/perl
use strict;
use warnings;
exit !main(@ARGV);
sub main {
my $fname = shift; # etc...
foo()
or return; # Will lead to a non-zero (i.e. unsuccessful) exit-code
return 1; # All went well (will lead to a successful exit code of 0)
}
sub foo {
}
And the reason for this is at least in part to avoid having unintentional whole-file-scope for the lexical variables in the 'main' code. Having the 'exit' in there too means one doesn't have to eyeball the entire file looking for executable code at file scope. (It does mean that if you want any file-scope lexicals, you need to put them before the call to 'main', but to me that's actually a feature.) | [reply] [d/l] |
Re: Confusion in naming variables in subroutines
by rkrieger (Friar) on Jan 24, 2007 at 01:18 UTC
|
As a general advice, pick variable names that clearly and specifically describe what they contain. In the long run (e.g. when you need to look at the code again in several months), that will keep things easier for you.
For a sub in which you calculate volumes and/or areas and the like, you can probably suffice with more 'generic' names such as $length, $width, $height, etc.
In your main program, you're more likely to deal with various lengths, heights, etc. For those, I would recommend naming them (for example) $box_width, $box_length, etc. if they're describing a box.
As you mentioned, little prevents you from scoping the variables and naming them similarly. Do as you prefer, of course, but from a maintainability perspective I recommend you make things stand out (i.e. use different names).
--
If you don't know where you're going, any road will get you there.
| [reply] |
Re: Confusion in naming variables in subroutines
by muba (Priest) on Jan 24, 2007 at 02:20 UTC
|
I'm under the impression that this is generally a good idea, as long as you use the same variable name for the same thing all the time.
For example, the code of the IRC bot I'm working on (yeah yeah, I know, yet another IRC bot) is really littered with $user and $channel variables. All in different sections of the code and in different subroutines.
$user holds the nickname of the user who is responsible for a given event (IE, the user who is talking, the user who changes a mode somewhere, the user who gives channel operator status to someone, and so on). In linguistics, this is often called the agent. (On a sidenode: whenever there is a patient, I usually store his name in $who. A patient is the user who, say, recieves operator status)
$channel holds the channel name of where this event occurs.
The bot of course keeps track of which users are in what channels.
But recently I had to revise the subroutine that handles KICK events. I used $user there too. But to my suprise I discovered the following (paraphrased) code:
delete $channelDB{$channel}->{$user}
Wait, what? Am I really removing the agent from the list? That's not supposed to happen! I of course want to remove the one who's being kicked, the patient. So I scrolled up in the code a bit to see in what variable I was storing the patient's username. Funnily enough, it turned out I was right with my delete $channelDB{$channel}->{$user} after all: I stored the patient in $user!
That, of course, is a Bad Thing. In every other subroutine (and let me tell you there are quite some subs in this whole thing), $user refers to the agent, not to te patient. In this case, I stored the agent in $kicker (which made me giggle when I saw that, because kicker sounds very similar to Dutch kikker, which means frog. Anyway...).
So. To get back at my point: re-using variable names in different parts of the code is okay, as long as one variable name always holds the same kind of value, in my opinion. That way you'll always be able to see that delete $channelDB{$channel}->{$user} removes the agent of an event from the list of users of the channel where that event occurs.
Of course, when I was revising the code for the KICK handler anyway, I also fixed it. $kicker was renamed $user, and what was $user is now $who. So whenever I need to change that subroutine again, I just know that $user kicks $who from $channel.
Edit: fixed a typo
| [reply] [d/l] [select] |
Re: Confusion in naming variables in subroutines
by pemungkah (Priest) on Jan 24, 2007 at 01:23 UTC
|
Using the same names is perfectly acceptable, as long as the names make sense in the context where they're used. I'd actually argue against $temp_length: is this a temporary variable that is needed so that the subroutine can perform its algorithm, and we'll be using the $length in the outer scope as well, or is it something else?
I personally just pass all the variables I need in, assign @_ to a list of variables on the first line of the subroutine, and use the names that seem most appropriate to describe what I'm doing. This may mean that in, for instance, a module that munges strings, that I have $string in several different subroutines.
Whatever keeps the algorithm clear in the reader's mind is what you want to use. | [reply] |
|
|
This is more a side note, I'll admit.
If you expect the number of arguments to grow, you may want to consider passing those arguments in the form of a hash and call routines with named parameters.
That way, you will not be bitten by having to remember the exact order in which you need to pass arguments. I find it's easier on others using my code.
| [reply] |
Re: Confusion in naming variables in subroutines
by ww (Archbishop) on Jan 24, 2007 at 02:16 UTC
|
I see nothing technically wrong with your style, nor with the endorsements above.
But I am still impelled to offer a contrarian view.
Look to the long view.
If the script is more than a one_off, one_use package, think of your successor, as you may wish a predecessor had thought of you.
Surely, that hypothetical maintainer, perhaps generations from now, will find it easier to distinguish one $var from another, if you take the minimally non-lazy way of naming the $vars in the sub something like $sub_length, $sub_breadth and $sub_height.
Imagine all that and add a few (not unreasonable, IMO) additional complications; namely, that your script has become a part of your organization's backbone... AND has been "enhanced" by some intermediate generations; that the "bells & whistles" they've added have muddied the waters; and that your sub now resides some hundreds or thousands of lines from its original position of prominence and its original clear relationship to the caller. | [reply] |
|
|
I will agree with your concept that having the same variable name(s) should not be used as a thumb rule. The confusion cropped-up as I wanted to use the same name in places where it made more sense rather than having different names in each of the subroutines.
In the below example, I get a session_id and I wanted to use in 3 different ( may be more.. ) subroutines. I felt odd to use different names for session_id in different subs. Hence, I posted the query to the Monks for some help..
#! /usr/bin perl
use strict;
use warnings;
...
...
# get session id
my session_id = get_cgisessionid();
...
...
sub a( $session_id );
...
...
sub b( $session_id );
...
...
sub c( $session_id );
..
sub a {
my $session_id = shift;
...
}
sub b {
my $session_id = shift;
...
}
sub c {
my $session_id = shift;
...
}
| [reply] [d/l] |
Re: Confusion in naming variables in subroutines
by roboticus (Chancellor) on Jan 24, 2007 at 13:43 UTC
|
I agree with most of the commentary I've seen thus far. However, if it concerns you, you might adopt the practice of having something different between global and local symbols, such as capitalizing the globals. This way, you won't be as easily confused when you're maintaining code in the future. For example, omitting 'my' on one of your variable declarations, and then having odd changes in your global variables...
--roboticus | [reply] |