Viewed   92 times

In PHP, I can write:

$vname = 'phone';
$$vname = '555-1234';
print $phone;

... And the script will output "555-1234".

Is there any equivalent in Perl?

Is there any way to constrain $phone to the scope of the local block, as if I'd written my $phone? Using my $$vname gives me "Can't declare scalar dereference in my at ..." errors.

 Answers

1

What you're attempting to do is called a "symbolic reference." While you can do this in Perl you shouldn't. Symbolic references only work with global variables -- not lexical (my) ones. There is no way to restrict their scope. Symbolic references are dangerous. For that reason they don't work under the strict pragma.

In general, whenever you think you need symbolic references you should use a hash instead:

my %hash;
$hash{phone} = '555-1234';
print $hash{phone};

There are a few cases where symrefs are useful and even necessary. For example, Perl's export mechanism uses them. These are advanced topics. By the time you're ready for them you won't need to ask how. ;-)

Wednesday, December 14, 2022
 
4

This is the updated example:

$params is an array.

 function insertToDB($params, $db) { //Pass array and db

        $fields = array();
        $conn = new mysqli('localhost', 'root', 'root', 'db') or die('XXX');     
        $stmt =  $conn->stmt_init();
        $stmt->prepare("SELECT * FROM ".$db); 
        $stmt->execute();
        $meta =  $stmt->result_metadata();
        while ($field = $meta->fetch_field()) { 
             $fields[] = $field->name;   
        }

        $fields = implode(", ", $fields);


        $placeholders = implode(',', array_fill(0, count($params), '?'));

        $types = '';
        foreach($params as $value) {
            $types.= substr(strtolower(gettype($value)), 0, 1); 
        }

        $ins = "INSERT INTO MYDB (".$fields.") VALUES (".$placeholders.")"; 

        $bind_names[] = $types; 
        for ($i = 0; $i < count($params); $i++) { 
            $bind_name = 'bind' . $i;
            $$bind_name = $params[$i];
            $bind_names[] = &$$bind_name;
        }
        if ($stmt->prepare($ins)) {
                call_user_func_array(array($stmt,'bind_param'),$bind_names); 
                $insresult = $stmt->execute(); 
        }
        return $insresult;
        $stmt->close();
    }
Wednesday, December 14, 2022
3

No, there isn't a built-in enum construct. Perl doesn't do a lot of strict typing, so I think there's actually little need for one.

In my opinion, the Readonly approach you used is solid.

There's also the more traditional constant pragma.

use constant {
    HOME   => 'Home',
    WORK   => 'Work',
    MOBILE => 'Mobile',
};

$phone_number->{type} = HOME;

Behind the scenes, it sets up a function for each constant that returns the value, like so.

sub HOME () { 'Home' }

I'd stick with Readonly unless you want to take advantage of that property, for example:

package Phone::Type;

use constant {
    HOME => 'Home',
    #...
};

package main;

print Phone::Type->HOME, "n";
Sunday, August 14, 2022
4

Never used any of those, but they look interesting..

Take a look at Gearman as well.. more overhead in systems like these but you get other cool stuff :) Guess it depends on your needs ..

Friday, November 11, 2022
 
4

Perl has Docopt as pointed out in the comments by @marderh. In addition, there are other modules that provide similar functionality such as Getopt::Auto, Getopt::Euclid, Getopt::AsDocumented …

Thursday, November 10, 2022
 
tom_kur
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :