Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing an array and a scalar to a sub routine

Status
Not open for further replies.

drkestrel

MIS
Sep 25, 2000
439
GB
I have method
ftpGet($$$)
where first parameter is $mode=A,B or N
parameter two is @list which is not applicable other than for mode N
parameter three is $subMode- only applicable to mode N

I have difficulties passing in the parameters @list in. It was definitely initialised before sub call.
Anyway, what should I be doing? I tried different permutations of
Code:
sub(@)
$mode = @_[0];
@list = @_[1];
$subMode=@_[2];
Tried replacing @ with $, and using sub($$$) instead of sub(@), also tried differnent permutaions of @ and $, but no luck.......

What should I really do?? :-(
 
I assume that you mean the array and sub_mode are only needed in mode 'N', if not, you can modify the if structure of my code. Also, it'd be easier to do it with an array reference, rather than the full array. try:[tt]
sub name ($$$)
{
my $mode = shift;
if ($mode eq 'N')
{
my $arrayref = shift;
my $sub_mode = shift;
my @array = @$arrayref;
}

...
}[/tt]

it may even be easier to split the sub into 4 subs, one for each mode, and one for shared code, but that's a matter of architecture. or something i commonly do for OO structures is have something like the following:[tt]
sub name
{
my $self = shift;
if (@_)
{
return $self->{NAME} = shift;
}
else
{
return $self->{NAME};
}
}[/tt]

two cases, set the name or return the name. only one will be called with an extra parameter. knowing how the subroutine will be called can make for simpler structuring, rather than adding an extra 'mode' flag. you could easily apply this to your sub. "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."
 
drkestrel,

When you pass an array as a parameter to a perl function it doesn't look like an array from inside that function, the function just gets a list of values which all look the same, you can't tell when the array finishes.

So. If you're passing an array to a function make it the last thing you pass, then you don't have a problem with not knowing how many elements it has. Mike
michael.j.lacey@ntlworld.com
Email welcome if you're in a hurry or something -- but post in tek-tips as well please, and I will post my reply here as well.
 
Mike,
Thanks for your last post, but confused about what you mean..... is it a pass by reference/value issue you are talking about here?
 
I tried the following
Code:
my $arrayref = shift;
my @array    = @$arrayref;

the outcome is that iterating through the @array, i found that it is empty.

I also tried
Code:
@array= shift;
, however, that means only populates the first element!

what have i done wrong?

Note, I have now changed the method signature so that the array is my last parameter. There is only three parameters- first two are scalar anyway!

 
'Programming Perl'(second ed.) has a good example on page 116. Plagerizing from Wall, Christiansen, and Schwartz with slightly expanded var names for clarity.

[psuedo-quote]
@last_elements = &popmany(\@a, \@b, \@c,\@d);

sub popmany
{
my $array_reference;
my @last_elements();
foreach $array_reference ( @_ ) { push @last_elements, pop [red]@$array_reference[/red]; }
return @last_elements;
}
[end psuedo-quote]

The first line passes references to arrays. Hard references point to the location of the variable in the symbol table - where they are in the memory structure. So, when you go to use one of the arrays in the sub, simply act like it is an array (start with '@') and name it with the pointer to the correct place in the symbol table, in this case that is in $array_reference.


Variable is an array named by $array_reference
|
|
[red]@$array_reference[/red]
|-------------------|
|
Points to the location of the array in the symbol table


HTH


keep the rudder amid ship and beware the odd typo
 
Sorry for being a bit thick (also only have the 3rd Ed of Programming Perl... what is thing thing call...)
Anyway, is your @last_element=&popmany(\@a,\@b,\@c,\@d) a statement actually within the sub routine or is it a calling staement?
Is it also the @lastelements that would behave as if it is just like the array that has been passed in?

Since I am only using 2 scalar+1 array, is there any simpler (or more reliable) way of achieving this?
 
Don't give up on references yet! Hang in there.... They are worth understanding.

redo-ing the quote with some anotations....

[psuedo-quote]
# this line calls the sub 'popmany' and stuffs the returned list into @last_elements
@last_elements = &popmany(\@a, \@b, \@c,\@d);

sub popmany
{
# simply controlling scope - 'my' makes the var private to this sub
my $array_reference;

# note that the 'my' makes this copy of @last_elements private to the inside of
# this sub routine. This is not the same variable as the one used above. Sorry,
# that is probably a little confusing, but, having done it, I will leave it to be
# consistent with the rest of the thread.
my @last_elements();

# pop the last element off the end of each array name passed in and store in
# a local copy of @last_elements
# foreach reference to an array, pop the array....
foreach $array_reference ( @_ )
{
my $tmp = pop @$array_reference;
push @last_elements, $tmp;
}

# return the list of the last element from each array back to the calling statement
return @last_elements;
}
[end psuedo-quote]

HTH


keep the rudder amid ship and beware the odd typo
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top