You can see if a scalar is read-only by using Scalar::Util::readonly. (That's the same as the Util routine several other people have mentioned, but the module was renamed, and now comes with recent versions of perl.)

However, I think you API is rather poor, and changing the API would relieve the need to check for read-only parameters. In general, you should only modify your parameters when you have /very/ good reason, because it isn't what your users expect.

Instead of taking in a name, a url, and a body, and refering them soley by their entries in @_, copy them into variables in your subroutine, and return the modified body.

Not only does this make your function behave the way callers are (more likely to) expect it to work, it makes the body of your function read more clearly. I noticed you refer to your paramters in the comments as "name", $url, and $body. So, taking from your lead...

#!/usr/bin/perl -w use strict; use warnings; use HTML::Entities; sub sanitize { my($name, $url, $body) = @_; # no name? $name ||= "anonymous"; # add missing protocol in $url if ($url && $url !~ /^\w+:/) { $url = "http://" . $url } # add missing protocol in link in $body $body =~ s{\[(.*?)\]}{ my $x = $1; if ($1 !~ /^\w+:/) { if ($1 =~ /\@/) { "[mailto:$x|$x]"; } else { "[http://$x]" } } else { "[$x]" } }gex; # don't let people put in html $body = HTML::Entities::encode($body); # Return modified body. return $body; } my $body = "Mail me at [bugs\@microsoft.com]."; my $url; my $name; $body = sanitize("", $url, $body); print $body, "\n";

Now, the varibles that are not assigned to in the mainline of the program aren't modified. You can pass in whatever you want in $name, without worring about if it's writable, because your copy of it will be. The API of your sub is more like it's users probably expect.

If you really want to not change the API of your function, so that you don't have to modifiy the existing callers, you can, near the return line, check for not defined wantarray, that is, if your sub is being called in void context (it's return value isn't being assigned anywhere), and do a $_[2]=$body.


Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).


In reply to Re: How do I check if a scalar in @_ is writable? by theorbtwo
in thread How do I check if a scalar in @_ is writable? by beppu

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.