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).
|