Reputation: 1458
Am trying to make a subroutine that replaces data depending on datatype: the problem is i can't get the datatype of the parameter, i used this:
sub replace {
my ($search, $replacement, $subject) = @_;
if (ref($search) eq "HASH") {
print "r is a reference to a HASH.\n";
}
elsif (ref($search) eq "SCALAR") {
print "r is a reference to a SCALAR.\n";
}
elsif (ref($search) eq "ARRAY") {
print "r is a reference to a ARRAY.\n";
}
}
my $str = "Foo";
my @arr = ("Foo");
replace($str);
replace(@arr);
But none works. am really new to perl
Upvotes: 1
Views: 82
Reputation: 66964
It is not stated what you want to do with it, but here's what is wrong with what you show.
The ref function shows the datatype of the reference subtmitted to it, or it returns an empty string if its argument isn't a reference at all.
So to get the expected behavior you should do
replace(\$str);
replace(\@arr);
Also, you need to add the test to your function
else (not ref $search)
for when a submitted string is not a reference.
For completeness, I should also point out an issue, explained in the answer by stevieb. When you pass an array to a function, it receives it as a flat list of arguments. With your function you clearly do not want replace(@arr)
. They are assigned to your list of scalar variables in order, one element to each. (As soon as there is an array variable it all goes into it.) See, for example, this post.
Upvotes: 1
Reputation: 9306
ref() takes a reference to something, not the something itself. Here:
replace($str);
replace(@arr);
...you are sending in the something directly. Send in a reference to the something instead, by putting a \
in front of it (which says, "take a reference to this something"):
replace(\$str);
replace(\@arr);
Output:
r is a reference to a SCALAR.
r is a reference to a ARRAY.
Note also that in your replace()
function, in this line:
my ($search, $replacement, $subject) = @_;
You are effectively asking for a scalar value as the thing to search, so passing in a list (array, hash etc) will clobber $replacement
and $subject
if the passed in list has more than one element, so you may want to do something like this to ensure you're getting the proper params, and nothing is clobbered unexpectedly:
sub replace {
my ($search, $replacement, $subject) = @_;
die "first arg must be a ref\n" if ! ref $search;
Of course, you can do further argument checking, but this'll ensure that the first parameter can only be a reference to something. Instead of die()
, you can also just return
so the program doesn't crash, or print
or warn
and then return
.
Upvotes: 4