Re: Is this bad coding style?
by bobf (Monsignor) on Jan 08, 2009 at 04:16 UTC
|
I know this is just an example, but strict and warnings can help nonetheless. In this case you define @arrray and loop over @array. OK, that's out of my system. :-)
A dispatch table might help, especially if you've got a lot of special cases. For example:
my %dispatch =
(
'#' => \&sub1,
1 => \&sub2,
);
my @array = (1, 2, 3, '#', 6, 7, '#', 9, 10); # corrected typo!
foreach (@array) {
if( exists $dispatch{$_} )
{
$dispatch{$_}->();
}
else
{
sub3();
}
| [reply] [d/l] [select] |
Re: Is this bad coding style?
by tilly (Archbishop) on Jan 08, 2009 at 04:53 UTC
|
In addition to what bobf said, writing $_ == 1 is dangerous because it is too easy to drop an = and assign rather than compare. (Warnings will catch that, but you probably don't have warnings.)
Depending on the circumstances, where one person would use your approach I might have an array of references to closures. Then I just call them. Like this:
my @array = (\&do_where_var_is_1,\&do_something_else, \&do_something);
+ # etc
$_->() for @array;
This may look convoluted, but when you are building up your array in code it is as easy to put code references in as values, and now you don't have to synchronize between the if logic where you do stuff and the logic where you build the array.
Also this code snippet has very badly named variables, arrays and functions. Probably that is because it is an example, but do be sure that real code is of better quality. | [reply] [d/l] [select] |
|
|
>perl -e"$_ = 0; die qq{uh oh!\n} if $_ = 1;"
uh oh!
>perl -e"$_ = 0; die qq{uh oh!\n} if 1 = $_;"
Can't modify constant item in scalar assignment at -e line 1, near "$_
+;"
Execution of -e aborted due to compilation errors.
| [reply] [d/l] [select] |
|
|
I swear that I meant to say that, and then I didn't. Thanks for saying it for me.
| [reply] |
Re: Is this bad coding style?
by fullermd (Vicar) on Jan 08, 2009 at 04:45 UTC
|
So $_ is compared against "# using "eq" (for strings) and against the integer 1 using "==" (for numbers). Is that a bad style?
Well, it would be much worse style to compare against # using ==, and against 1 using eq :)
It can be a perfectly reasonable means to an end. Whether it's a reasonable means to this end, though, is pretty hard to say. Particularly since there's no end suggested, just a means.
Depending on the end, the above suggestion by bobf could be a better means.
| [reply] |
Re: Is this bad coding style?
by JavaFan (Canon) on Jan 08, 2009 at 10:29 UTC
|
In 5.10, you can let Perl worry about when to use eq and when to use ==:
for (@array) {
when ("#") {do_something()}
when (1) {do_where_var_is_1()}
default {do_something_else()}
}
Note that your code will give a warning if the @array contains '!', or any other string that doesn't look like a number and isn't equal to '#' | [reply] [d/l] |
Re: Is this bad coding style?
by leocharre (Priest) on Jan 08, 2009 at 16:48 UTC
|
Bad coding style is a little vague..
You could be meaning syntax- which is more about formatting- or maybe symbol names (variable names, etc) - or your lack of use strict, or your use of foreach instead of for.. etc etc.
Here's how I would naturally code this, myself..
my @a = qw/1 2 3 # 6 7 # 9 10/;
for my $val ( @a ){
$val eq '#' ? do_something()
: $val eq '1' ? do_where_var_is_1()
: do_something_else();
}
Why am I naming a variable $val instead of simply using $_ ? Because it's more intuitive when I look at it- to mean that I am checking that value, if I were using the value, I may name it $arg.
Why use a for instead of foreach? I use foreach with hashes, for with arrays, something personal.
Why use the ternary operator instead of if and else? For brevity and because it rocks.
Why do I use eq for both 1 and # ? Because it makes the code make more sense for human eyes. ( Besides you don't need to differentiate between numbers and strings here- they are all strings, right? That is, it appears the sample data you may have is by default all string- and it may be a character number or something else. You can't have all numbers and one character and still have all numbers, but you can have all c... anyways.. )
That's what *I* would do naturally. But everyone has a style. What's important is that is work, and it's also important that another coder can look at it and easily tell what you are doing.
| [reply] [d/l] |
|
|
Thanks, leocharre.
What if @array was populated like this:
my @array = (1 .. 9); # real numbers
push(@array, '#');
Does it still make sense to use "eq" and compare each of the elements of @array with '1' ? ie. if ($var eq '1');
| [reply] [d/l] |
|
|
Yes, that's fine, but.
It would be more useful to ask "will this give me the output I want" (with a sample output provided) rather than "is this code OK". This is the equivalent of saying "perl -c reports no syntax errors - guess it works!" instead of "my tests pass - guess it works!".
- Do you want to use the # as a delimiter in the array?
- Do you want to throw out any '#' entries?
- Is there some other result that I haven't guessed?
To make sub-arrays at each '#':
use strict;
use warnings;
use Data::Dumper;
my @broken_up;
my @array = qw( 1 2 3 # 4 5 # 6 7 8 9 # 10);
my $position = 0;
$broken_up[0] = [];
foreach my $item (@array) {
if ($item eq '#') {
$position++;
$broken_up[$position] = [];
}
else {
push @{ $broken_up[$position] }, $item;
}
}
print Dumper(\@broken_up);
gives
$VAR1 = [
[
'1',
'2',
'3'
],
[
'4',
'5'
],
[
'6',
'7',
'8',
'9'
],
[
'10'
]
];
Now you have an array of arrays, broken at the '#'s. (The extra level of nesting is because I dumped a reference to the output array.)
If you just want to throw the '#'s out:
@array = qw( 1 2 # 3 4 5 # 6 7 8 9 # 10);
@array = grep { $_ ne '#' } @array;
print "@array\n";
gives
1 2 3 4 5 6 7 8 9 10
Notice that these are wildly different, because we don't know what you're actually trying to do. Obviously it doesn't matter whether or not the style is good ... if the result is wrong. :)
| [reply] [d/l] [select] |
|
|
Well, would you know that these are all numbers? Or that they are not all numbers?
Part of the strength (or weakness) of perl- is that it's not strongly typed. That means, you can define a symbol ( create a variable name like 'my $a;') before you say what the heck it is supposed to hold.. and .. well.. there's some more to it.. basically you let perl worry about it.
Look up strong vs weak typed languages on google.
| [reply] |