Member Rara Avis
Yes, you can pass values into a routine (with some limitations). You can get values back out of a routine, too (with the same limitations).
You pass values into a subroutine like this: Cookies("set"); or, with multiple values, like Routine($value1, $value2, @array). The way you've been calling routines, with the leading ampersand (&Routine ;) is deprecated and will eventually be replaced with Routine() (even with no parameters passed).
The values that you pass in the parenthesis of your subroutine call are placed into the special Perl array @_ and it's entirely up to your subroutine what to do with them. Notice in the Cookie subroutine, the first thing that happens is that $action is assigned to $_? If there were more scalar values being passed, the routine would simply grab each subsequent value, so you might see $value2 = @_ and $value3=$_. Another way to do the same thing, and one I use a lot, would be ($value1, $value2, $value3) = @_. This depends on the fact that scalar variables enclosed in parenthesis are equivalent to a list and is functionally no different than the way many arrays are assigned [such as @array = (1, 2, 3, 4)]. It just reverses the concept.
What you'll see in a lot of programs, instead of a direct assignment, is the shift operator. It's very common to do $action = shift; $value2 = shift; etc. The shift operator pulls the leading value off an array (and @_ is the default array if none is specified), and I mean literally pulls. After a shift operation, what was the second element of the array has become the first element. You'll rarely see me use the shift operator to grab parameters for that very reason - it's moving the whole array with every execution and is one of the slowest of all Perl's operations. Explicit assignment is much faster.
The exception to that rule, however, is when you pass an array. Notice in my second paragraph above that I said we could something like this: Routine($value1, $value2, @array)? This is perfectly legal and common, but it's also a little tricky to understand the limitations. You are essentially passing an array INSIDE of another array (the special @_ array). That will only work if the array is the LAST parameter you pass and, by extension, that means you are limited to passing only one array into a subroutine. Getting those parameters back out of the @_ array then makes good use of the shift operation.
$action = shift; # pull first element off the @_ array
$more = shift; # pull what has become the first element off
@rest = @_; # get everything still left in the @_ array
Returning values from a subroutine follows basically the same path, though it does not involve the special @_ array. If you call a subroutine like $returnValue = Routine();, then your Routine should end with a return $something;. Multiple return values follow the same rules as when passing variables.
($value1, $value2) = Routine(); should be matched with return ($some1, $some2);
@array = Routine(); should be matched with return @something; [or]
@array = Routine(); might be matched with return ($some1, $some2, $some3);
($value1, $value2, @array) = Routine(); might even be matched with return @bigArray;
The rule of thumb is that passing values into a routine, or returning values from a routine, always involves an array - even if the array isn't obvious. In my last example above, I'm taking a bigger array, assigning the first two elements of it to scalar variables and the rest to a smaller array. It's still all an array, and how I break them up is my call.
Now, to answer your REAL question. :)
To use the Cookie subroutine, you should first assign the values you want to the %cookie hash. This is a global hash because - guess what? - the one thing you can't easily pass to a subroutine is a hash. Once the hash is assigned, you can then call Cookie with the appropriate $action parameter.
Cookie("set"); # prefill the hash
Cookie("get"); # the hash will be filled FROM the cookies
Cookie("clear"); # hash isn't even referenced