-
Website
http://carlo.zottmann.org/ -
Original page
http://carlo.zottmann.org/2007/07/03/unsetperl/ -
Subscribe
All Comments -
Community
-
Top Commenters
-
Vicki
1 comment · 1 points
-
Hendrik Mans
3 comments · 2 points
-
Daniel Ha
2 comments · 405 points
-
kentbrew
4 comments · 2 points
-
Mark Douglass
3 comments · 2 points
-
-
Popular Threads
my @indices = grep { $array[$_] eq 'foo' } 0 .. $#array;
which is not very cool if you have large arrays. But who knows what other languages do in the background of their convenience methods?
You should think about using a hash here. To keep things in order you could use Tie::IxHash.
But I agree, Perl is very "old school"...
> But who knows what other languages do in the background of their convenience methods?
The question is: should I care? Shouldn't a programming language get out of my way instead and help me to ideally achieve the highest state of productivity?
$i=$array->aindex('foo');
-Ben
Try using the right tool for the right job. Irrespective of the language, the fact that you want this out of an array indicates that your data may have been coerced into that 1D structure where a richer structure should have been used.
As others have mentioned, there are many simple ways in perl to do what you want. However, perl itself is not offering such a method that's ultimately helping you shoot your own foot off.
Think about it for a bit. What if the array has a huge data set ? What if it had duplicates of what you want ? Do you want the first match, middle match or last match ? do you want to optimize by stopping the search after a match ? Will you re-search the array again for the same key ? For a different key ?
To answer your question: Yes, absolutely you should care. Hardware is cheap and programmer's time is valuable, but simple understanding of basic optimization and the right modeling for the right problem will make the difference between your application not making a nudge in resource usage vs. large hiccups and needing exponentially more hardware when you grow and scale.
Actually, I did. I used an array because I have a _very_ limited amount of _unique_ strings, and I don't need anything fancy at all. Using a hash felt like overkill, but I by now believe I was wrong. That said, I don't want to go into more details about what I was trying to do, mostly because (A) of an NDA and (B) it was just a(nother) particular thing that ticked me off.
A few other pet peeves: for a language that's about text extraction and manipulation, I really miss a built-in `trim()` function of sorts (which rids a string of leading and trailing whitespace). And why is there no `switch()`?
But to clarify: if I could choose, I would ditch Perl in favor of something that makes more sense (to me). Python comes to (my) mind. Unfortunately, I don't have that choice -- the company policy is to use Perl for this field of backend code, so I have to deal with it.
EITHER WAY: Thanks for the suggestions.
switch... that's a little tougher. how about the "cannonical":
SWITCH: for ($variable) {
($variable eq "thing1") && do {
do_neat_stuff();
last SWITCH;
};
($variable eq "thing2") && do {
do_more_neat_stuff();
last SWITCH;
};
...
}
Ah, perl... :)
And the `switch`... It might work, but it's fugly and definitely more work than it should be. :P
set(Perl) while(1);
Also: trimming a string is something Perl isn't suppose to do in the first place?
Use Perl all you want, that's cool, but please don't tell me it's elegant.
Oh, since the most elegant (yes, in relative terms of course...) method wasn't mentioned yet:
use List::MoreUtils;
my $i = first_index { $_ eq 'abc' } @a_list;
my $i = first_index { m/abc/ } @a_list;
http://search.cpan.org/perldoc?List::MoreUtils
http://perldoc.perl.org/perl587delta.html#Optio...
I see your basic complaint as being that arrays, strings, etc. aren't objects with a rich set of methods. This is true, but not actually that big a deal. Given that the
main types aren't objects, to avoid namespace pollution, Perl defers a lot of functionality to modules. Text::Trim provides trim, ltrim, and rtrim functions.
With respect to the array index problem, others have suggested modules that
allow you to have an array interface but also lookup by value. There isn't something that I know of that works on a basic array rather than a tied
array or an object initialized from an array. I suspect this is because idiomatic
perl tends to use array indexes very very rarely. In fact, using an array index is usually a big clue that you need to rethink your storage (which it sounds like you've done.)
I'll finish with this:
my %array_index_for_value = map $array[$_] => $_, 0..$#array;
@names = qw(bob mary jane mark jane steve);
@indexes{@names} = 0 .. $#names;
While it may look like "indexes" is an array, it's actually a hash being vivified and populated with a huge slice (the array of names)....
use Data::Dumper;
print Dumper \%indexes
One person noted a trim module, but there is also the builtin chomp() function which removes trailing whitespace (no modules needed) - but I believe it only removes one character, so it needs to be run in a loop if it's indefinite.
As for perl not having switch, try "use Switch;" It's actually a well-done switch setup and I believe it's standard in most perl distributions.
Mostly though, I think perl is as flexible as you are saying it isn't, but you should check out CPAN before looking to write your own code. I have frequently started to write large blobs of code, only to search CPAN and fine that a more robust and elegant solution is available. I now tend to search it before doing any wacky programming.