Re: Passing Any Range of Values to a Sub (slice)
by tye (Sage) on Jul 02, 2003 at 03:37 UTC
|
If you run "script add 2 1 3 7 5" then your $ARGV[1]..$ARGV[$len] boils down to 2..5 which is the same as 2,3,4,5. You are close. You want 1..$len and use that to get items from @ARGV. That is called an "array slice" and is written @ARGV[1..$len] (note the @ not $).
- tye
| [reply] [d/l] [select] |
|
|
Of course, and array slice, I've used them before, but it never came to me when trying to figure out this problem. Thanks a million.
| [reply] |
Re: Passing Any Range of Values to a Sub
by The Mad Hatter (Priest) on Jul 02, 2003 at 03:37 UTC
|
Update TIMTOWTDI, as seen by tye's post below. All a matter of perspective. ; )
In this case, you don't want to use the .. operator (which produces consecutive numbers), you just want to pass a list of values. @ARGV contains this list, except for the first element, which is the operation. So shift off the first element from @ARGV, figure out what to do, pass the rest of @ARGV to the appropriate function, and you should be set.
I'd suggest you figure it out yourself, but here's the code if you really want to see it...
| [reply] [d/l] [select] |
Re: Passing Any Range of Values to a Sub
by bobn (Chaplain) on Jul 02, 2003 at 05:05 UTC
|
Congratulations on use of warnings and strict. You'll save much heartache down the road that way.
my $op = shift @ARGV;
# first element of @ARGV now in $op and removed from @ARGV.
print add(@ARGV) . "\n" if $op eq 'add';
print multiply(@ARGV) . "\n" if $op eq 'multiply';
# subs as before
Or you can get fancy and have a hash table of functions:
my $op = shift @ARGV;
# first element of ARGV in $op and removed from @ARGV.
my %h = ( add => \&add, multiply => \&multiply);
print $h{$op}->(@ARGV) . "\n";
# subs as before
--Bob Niederman, http://bob-n.com | [reply] [d/l] [select] |
Re: Passing Any Range of Values to a Sub
by bart (Canon) on Jul 02, 2003 at 08:18 UTC
|
Your problem has been solved several times over from what I see... But as for alternatives, may I point you towards reduce(), available in List::Util? Your multiply and add functions are typical examples to be implemented this way.
use List::Util 'reduce';
my $op = shift @ARGV;
if ($op =~ /add/) {
my $sum= reduce { $a + $b } @ARGV;
print "The sum is $sum\n";
}
elsif ($op =~ /mult/) {
my $product= reduce { $a * $b } @ARGV;
print "The product is $product\n";
} else {
print "Huh? I don't know how to '$op'?\n";
}
Yes, that's all the code it needs.
| [reply] [d/l] |
Re: Passing Any Range of Values to a Sub
by Petras (Friar) on Jul 02, 2003 at 10:13 UTC
|
I'm ashamed to admit it, but yes this is homework.
Hey, at least you had the umption to admit it upfront. There are a lot of posts that stink of homework questions but start off with something like, "SO I was playing around with Perl and had an idea but I can't make it work...." which translates to, "This is due tomorrow. Help!!!"
What makes this a good post is that- You admit upfront that it's homework (show some integrity!)
- You did some work, and it looks like some research (not just "How do I do this thing?")
Keep working at it. You'll pass me in no time (if you haven't already ;)
Cheers! Petras Don't worry about people stealing your ideas. If your ideas are any good, you'll have to ram them down people's throats.
-Howard Aiken
| [reply] |
Re: Passing Any Range of Values to a Sub
by kabel (Chaplain) on Jul 02, 2003 at 05:19 UTC
|
to live TMTOWTDT out, here are some other ways;
one cannot recommend the first one, but the second is a clean way:
1. a nice eval-trick, i think abigail-II used it in a sig
eval join ('*', @list);
2. something more functional?
have a look at Language::Functional. the relevant bits are the functions foldl/foldr
$x = foldl { shift() + shift() } 0, [1..6]; # 21
this is the POD example.
HTH a bit at least :-) | [reply] [d/l] [select] |
|
|
print eval join (shift @ARGV eq 'add' ? '+' : '*', @ARGV);
Fun, but maybe a bit unclear ...
| [reply] |
Re: Passing Any Range of Values to a Sub
by David Caughell (Monk) on Jul 02, 2003 at 05:43 UTC
|
Hi there.
I'm also a student learning the language.
Personally, I think it's best to always use:
my $size = scalar(@testarr);
rather than:
my $size = @testarr;
Because it's easier to understand and by naming something you exert a little more control over it. It also helps stress the difference between scalars and arrays, which is helpful for me as a student.
I'd be interested in knowing what the more established users of the language think about using scalar() rather than using only the array.
Any comments?
David Caughell.
Barrie, Ontario, Canada.
| [reply] |
|
|
If it's clearer for you and the people you work with, go ahead and use it. Maintainability and clear communication trump just about any other concern.
I personally don't care for it because I'm used to context. It's effectively a no-op, and, if I don't have to worry about the maintainability burden to someone who doesn't have a firm grip on context (and I usually don't), I prefer to leave out unnecessary code.
You'll probably find yourself using it less and less often as you continue learning.
| [reply] |
|
|
That makes sense, thanks a lot!
I'd prefer to send a message like this privately, but I don't think I can do that. If there's a way of sending PMs here, someone please send me one and let me know!! :)
Update: to send someone a private message, just type /msg username message in the chatter box and hit "talk".
--Dave
| [reply] |