views:

72

answers:

4
#! /usr/local/bin/perl 
sub getClusters
{
my @clusters = `/qbo/bin/getclusters|grep -v 'qboc33'`;
chomp(@clusters);
return \@clusters;
}

ummm okay .. how do I get at this array to print since ...

foreach $cluster (getClusters())
{ print $cluster."\n"; }

doesn't seem to work. Thanks.

+5  A: 

You are returning a reference, and not dereferencing it anywhere.

foreach $cluster (@{getClusters()})

OR

return @clusters;

Either should fix it (with slightly different effects), with the first one being preferred (your array is kind of big).

You'd use the non-referenced array return for limited number of elements, usually for the purpose of multi-return (thus, usually, limited to 2 or 3, known-length arrays).

Amadan
-1, returning an array over an arrayref is bad advice. Remove that part and +1
vol7ron
@vol7ron: Not advice, I just said what will work. You do have a point, however. I made it explicit when to use which. (Returning an array has its place, thus I prefer to clarify instead of remove.)
Amadan
+1. There's nothing at all wrong with returning an array. There are lots of things to consider, such as the typical array size, and how the sub will behave in context.
friedo
+1 returned for your edit. I want to also correct my comment: my comment, a list is being returned, not an array. Still, there is a performance hit, where one doesn't need to occur, as minimal as it is, arrayrefs should still be encouraged.
vol7ron
+1  A: 

If you ran your program under use strict; use warnings;, it would have told you why it failed. As Amadan said, you need to dereference the reference you return.

Daenyth
A: 

To make it easy, you can first receive the return value and then print it like

use strict;
use warning;
my $cluster_array = getClusters();
 my @cluster_return = @{$cluster_array};
foreach my $cluster(@cluster_return){
 print"$cluster\n";
}
Nikhil Jain
+1  A: 

Perl Solution

#!/usr/local/bin/perl
use strict;
use warnings;

main();

sub main{
   {
      local $"    =  "\n";
      print "@{getClusters()}";
   }
}  

sub getClusters{
   my @tArray  =  `/qbo/bin/getclusters|grep -v 'qboc33'`;
   chomp @tArray;
   return \@tArray;
}

Notice

  1. You don't need a foreach loop for debugging, you can just reset the $" operator however to separate array elements however you like (eg, , ,, or how I set it in the code above \n).
  2. Returning an array ref is a plus, don't send back the full array (good job)
  3. use strict/warnings, especially when debugging
  4. try to avoid system calls using ``
vol7ron
I still like this solution better as it introduces the `$"`, one of the more uncommon special variables, which reduces the need for a loop in this case.
vol7ron
But you modify `$"` over the entire program. `local` means that `getClusters` and anything it calls will see the modified value. With something as heavily used as `$"`, you are begging to break a larger program. If you must munge globals, restrict the effects as tightly as possible. This is much safer: `my $clusters = getClusters(); { local $" = "\n"; print @$clusters; }`
daotoad
**@daotoad:** You made an excellent point, which I credited, however that is why local was used - it only applies it to the main function and any subroutine called within it. **Note:** your `@$clusers` needs to be contained in a set of double quotes (`""`). Also, `$"` is not used that heavily, primarily in debugging. **Update:** I've modified the code, if `getClusters()` is a special case that requires the `$"` to be at it's default, it can define `$"=' '` inside it. Otherwise, limiting to a sub-block of main is fine.
vol7ron
I'm not sure why this answer is being downvoted, it is superior in explanation and example.
vol7ron