hakkum:

I assume you mean to rather call it with the hash key, as in: print random_password($cli_options{l}) . "\n";. Is that correct?

Exactly right. In a small program it may seem awkward, but when you have a program with many bits of code that access information from anywhere, it becomes harder to understand the program, making it harder to change it. Additionally, if you decide you want to transplant a function into a new program or module, it's easier to extract it when there aren't any hidden interactions.

And if so, as opposed to using my ($pass_len) = @_; to store it, shouldn't I rather do my $pass_len = shift;? Or am I missing something?

Either form is just fine. In fact, until recently I *always* used shift. Normally, there's little difference between them:

my log_msg_1 { my $FH = shift; my $msg = shift; print $FH $msg; } my log_msg_2 { my ($FH, $msg) = @_; print $FH $msg; }

The log_msg_1 and log_msg_2 subroutines are equivalent. I prefer the second form primarily because it makes the argument list obvious, so I can remember the argument list with a brief glance at the subroutine. The fact that it makes the code a little smaller is a happy side-effect. In fact, if I could make any single change to the syntax of perl, I think it would be to allow function declarations to be of the form:

my sub log_msg ($FH, $msg, @args) { print $FH $msg, @args; }

be equivalent to:

sub log_msg { my ($FH, $msg, @args) = @_; print $FH $msg, @args; }

Having said all that, there is a *small* difference between the two forms: The version using shift alters the @_ array. This won't normally make a difference to you, but if you review perldoc perlsub, you'll see that if you call a subroutine like &subname;, then subname will receive the current @_ array as its argument list. So you can do something like this:

#!/usr/bin/perl use strict; use warnings; use POSIX qw(strftime); printit("Foo", "bar", "baz"); log_time("Foo", "bar"); sub log_time { my $time=strftime "%H:%M:%S :", localtime; unshift @_, $time; &printit; } sub printit { my (@args) = @_; print join(" ",@args), "\n"; }

Here, the printit subroutine just puts a space between all the arguments and prints them with a linefeed at the end[1], and the log_time function simply adds the formatted time to the start of @_ and then calls printit with the current argument list. Since shift takes the first item off the @_ array, then calling another function like &subname; will call that function with fewer arguments. If you don't expect it, it can be quite surprising. When you're aware of it, though, you can find interesting ways to use it.

[1] I originally tried using the print function instead of printit to simplify the code, but it complained about &main::print not existing, so rather than figure out how to use the trick with print, I just made my own version of print. I suspect a more experienced/knowledgeable monk will chime in with a clarification on that point.

...roboticus

When your only tool is a hammer, all problems look like your thumb.


In reply to Re^3: Please Review First Program: Random Password Generator by roboticus
in thread Please Review First Program: Random Password Generator by hakkum

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.