> Wiggins d Anconia said: <snip>
> > > > sub links { > > my ($base_url, @list) = @_; > > foreach my $element (@list) { > > print ..... > > } > > return; > > } > > Doesn't this still get the scalar and array from what I defined at the top? > No, note that I have changed the names (on purpose) so that they are defined specifically to the sub (as your other email mentioned). Since I have given them new names they are essentially copies of the original data, but since the variables are within the scope of the sub I can now take the sub and drop it into a library and it will still work, though the calling syntax has to be different (see summary below). > Also, why do you assign them to @_, can't we use that when iterating @list? > I am not assigning them *to* @_, but *from* @_. In other words, when the subroutine is called it automatically stuffs the arguments given to it in @_. Then within the subroutine I want to pull those arguments back out of @_ and use them to do something (you don't really have to give them new names, but accessing into @_ as $_[0], $_[1], etc. gets annoying). Of course that is where hashes come into play :-)... > Why wouldn't it accept it's arguments? In your case you were not using the @_ values so it was not expecting (or using) the arguments, and your calling syntax of C<links()> indicates that no arguments are being passed. > > >> ----------------- > >> > >> I would normally call the subroutine like &links; but I want to put the > result into a variable in order to stick it into an e-mail. I have been > trying all day reading all my perl books and it's time to ask for help. > >> > > > > Note that we don't want to call C<&links> that is better written as > C<links()>. > > > > What is the result? In your case you are printing the links, so there > is no real result. > > That is what I want, but I can't figure how to but the list into the > e-mail message. See summary below... > > > You need to decide what the return value of the sub > > will be, maybe the list of urls? > > A list of urls. Ok. > > > a bool? undef for positive or an > > exception for failure? In the case of the list you should be C<push>ing > the values to list and then returning the list. In this last case we > can call the sub such as, > > > > my @ahrefs = links($website, @pics); > > I get this part. > > > foreach my $link (@ahrefs) { > > print "$link<br />\n"; > > } > > Isn't the above the same as my subroutine? > Sort of, except I have broken the different functional components apart and can now reuse C<links()> as a sub to build a list rather than to *print* a list. But in some cases I want to print a list, so I just print it afterwards. > > For instance. > > > >> Thanks. > >> > > > > Give it a shot, see if this helps, if not come back and ask more. > > Much appreciated. I will be re-reading Ch2-4 of the Lama tonight. > The llama is excellent. Ok so for the summary, Starting over with your sub that breaks encapsulation by not accepting arguments, and not returning a value, and has the less portable benefit of always printing the values (despite the fact that sometimes we might want them returned to us). my @pics = (list); my $website = 'url'; links(); sub links { foreach (@pics) { print "<a href=\"$website/$_\">$website/$_</a>\n"; } } So in the above your sub *assumes* @pics and $website exist. We want to switch it so that the sub assumes nothing and accepts all of the info it needs as arguments. So we get, my @pics = (list); my $website = 'url'; links($website, @pics); sub links { my ($url, @list) = @_; foreach my $element (@list) { print "<a href=\"$url/$_\">$url/$_</a>\n"; } } Notice that the call to the sub changed, and that it now doesn't use either of @pics, or $website, which means that it could be a list of anything and the $website is really just a base url. But we are still stuck with it just printing to STDOUT, so lets make it return a value instead making it more useful for other things... my @pics = (list); my $website = 'url'; my @piclinks = links($website, @pics); # now @piclinks is just a list that we could put in an email instead print for @piclinks; sub links { my ($url, @list) = @_; my @return; foreach my $element (@list) { push @return, "<a href=\"$url/$_\">$url/$_</a>\n"; } return @return; } So again I changed the call to now catch what the sub returns, and stopped the sub from printing the links. Inside of the sub I built a temporary list and returned it so that the caller could catch it and use it. (I have specifically left out the syntactic sugar of editing the elements in place, etc. for clarity since we are discussing subs not shortening of code.) So why is this better, still does the same thing? Mostly because it is reusable now. For instance, my @piclist1 = (list); my @piclist2 = (a different list); my $website = 'url'; my @email_list = links($website, @piclist1); my @db_list = links($website, @piclist2); # send an email with @email_list # store to a database with @db_list Now your sub is generic, it doesn't rely on the specific names, @pics and $website, and doesn't cause data to be printed when you might not want it to. Obviously this is a contrived example but as things get more complex it becomes absolutely critical. HTH, http://danconia.org -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>