Hello Monks,

I am currently modifing a subroutine(later to be added to a module) which I use often. The subroutine's name is masked_read. I have prototyped it to take two optional arguments, one being a scalar variable, and the other being any scalar like so: sub masked_read(;\$$). However, I have two questions:

Read more for my current code and a more detailed description of what I am trying to accomplish:
The following is a function with some code so it can be used if neccessary:
use Term::ReadKey; sub masked_read(;\$$) { my $mask; if($_[1]){ if(length $_[1] > 1){ die "arg 2 of masked_read() should only be 1 character long"; } $mask = $_[1]; } else{ $mask="*"; } my $key; $|=1; while(1) { while(not defined($key = ReadKey(-1))) {}; if(ord($key) != 13) { if(ord($key) == 8) { print "\b \b"; chop(${$_[0]}); } else { ${$_[0]} .= $key; print "$mask"; } } else {last} } $|=0; return ${$_[0]}; } print "Enter:"; my $password = masked_read; print "\npassword:$password";

The first Question:

Currently, when called two arguments are passed. The function can be called in any of the following ways:
masked_read($password, $mask); masked_read($password, '#'); masked_read($password); my $password = masked_read();

However, I would like the user to also have the following option: $password = masked_read('#')

I have already considered simply switching the order of the two parameters; however, that leads to syntax such as: masked_read('#',$password) . Which is counterintuitive and creates the problem of getting the scalar variable when the first value is not present.

I have also thought of creating a if-then structure to determine what the user has passed, but cannot think of or find a way to determine whether something is a variable or not.

This issue is the one that has stumped me, and any direction at all would be helpful.
Second Question:

As you can see I am currently using the length function to catch arguments in $_[1] that is more than one character. Right now this is needed because the method I use to mask the password on the screen does not work with a mask of more than one character if the person enters a backspace. This works fine, however I was wondering if there was a more efficient way of doing this. I looked through most of the information I have on prototyping and I did not see any way to accomplish it through prototyping means. If anyone knows of an alternative, it would be very helpful.


I realize this subroutine is pretty trite however I am doing this mostly as a means to learn about prototyping, subroutines, and later, making modules.

Thanks in advance.
Missing Words.

In reply to Subroutine Prototyping/Subroutine Argument Parsing by Missing Words

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.