Ghostff
Ghostff

Reputation: 1458

Perl get parameter datatype

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

Answers (2)

zdim
zdim

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

stevieb
stevieb

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

Related Questions