You are most welcome. Yes, that is exactly why i use shift. shift returns the first value from an array, in this case it is the implied array @_ which is used by Perl to store the arguments passed to a given subroutine. I could have used this instead:
my $filename = shift @_; # or even my ($filename) = @_; # multiple arguments are best caught this way: my ($first,$second,$third) = @_; # but some folks prefer my $first = shift; my $second = shift; my $third = shift;
Most (if not all...) other languages use an argument list to specify what a subroutine can be 'passed', as well as a return type (together these form the 'signature'). For example, in Java, these:
public static void do_something(String str) { System.out.println("got " + str); } public static void do_something(String str, int numb) { System.out.println("got " + str); System.out.println("got " + numb); } public static int do_something() { return 42; }
are three different functions with the same name. Perl chose instead to pass arguments in a list named @_. This is more flexible:
sub do_it { my ($str,$numb) = @_; print "got $str\n" if $str; print "got $numb\n" if $numb; return 42; } # and you call it like so: do_it('Hello World'); do_it('lucky number',7); print "the answer is ", do_it(), "\n";
How's that for flexibility! ;) Of course, with great power comes great responsibilty, and it is very easy to 'shoot your foot'. Some folks curse Perl for this power. The Python folks decided to allow named args, like so:

(subroutine lifted from python.org)

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while 1: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return 1 if ok in ('n', 'no', 'nop', 'nope'): return 0 retries = retries - 1 if retries < 0: raise IOError, 'refusenik user' print complaint quit = 0 while not quit: quit = ask_ok(prompt = 'Do you really want to quit?')
But with our own Ovid's Sub::NamedParams, we can do the same in Perl:
use strict; use Sub::NamedParams qw(wrap); wrap( 'sub' => 'ask_ok', names => [qw(prompt retries complaint)], hashref => 1, default => { prompt => 'Enter answer:', retries => 4, complaint => 'Yes or no, please!', } ); sub ask_ok { my ($prompt,$retries,$complaint) = @_; { print $prompt; chomp (my $answer = <>); return 1 if $answer =~ /y\b|ye\b|yes\b/; return 0 if $answer =~ /n\b|no\b|nop\b|nope\b/; $retries--; die 'refusenik user' if $retries < 0; print "$complaint\n"; redo } } my $quit; while (not $quit) { $quit = ask_ok({prompt => 'Do you really want to quit?'}); }
There is more than one way to do it. stephen wrote Attribute::Default to handle the same problem. The trick to this module is that you have to subclass the package - but who says main can't be a subclass? Named arguments are accessed through a hash:
use strict; use base qw(Attribute::Default); sub ask_ok : Default({ prompt=>'', retries=>4, complaint=>'Yes or no, +please!' }) { my %arg = @_; { print $arg{prompt}; chomp (my $answer = <>); return 1 if $answer =~ /y\b|ye\b|yes\b/; return 0 if $answer =~ /n\b|no\b|nop\b|nope\b/; $arg{retries}--; die 'refusenik user' if $arg{retries} < 0; print $arg{complaint}, "\n"; redo } } my $quit; while (not $quit) { $quit = ask_ok(prompt => 'Do you really want to quit?'); }
Both of these require a bit more work than Python - but remember that this functionality was not built into Perl 5 and Python 2 had the advantage of coming out after (but i still think named and default args a bit overrated, personally). Perl 6 will remedy this (thanks for the confirm Elian).

(thanks to chromatic for catching a silly error)

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)

In reply to More than you ever wanted to know about shift @_ by jeffa
in thread How to open sub FH when filename is passed to sub? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.