0

I've seen questions for the equivalent of PHP's compact function in other languages but not Perl so forgive me if this is a repeat to something I missed. If you are unfamiliar with this function here is what I'm looking for.

Given variables:

my $one = "1";
my $two = "2";
my $three = "3";

#using compact as example here since this function doesn't exist in perl
my $array = compact("one","two","three");

Then dumping $array would give:

[
    one => "1,
    two => "2",
    three => "3"
]

From the PHP documentation for compact:

Creates an array containing variables and their values.

For each of these, compact() looks for a variable with that name in the current symbol table and adds it to the output array such that the variable name becomes the key and the contents of the variable become the value for that key.

I am specifically working with version 5.8.8. Forgive me if some of my syntax is off. My background is PHP.

Community
  • 1
  • 1
dooplenty
  • 124
  • 7
  • 3
    What are you trying to accomplish that requires compact()? – Hunter McMillen Sep 23 '14 at 20:11
  • 2
    I may be misunderstanding, but that looks a lot like [using variables as variable names](http://perl.plover.com/varvarname.html). Yuck. – ThisSuitIsBlackNot Sep 23 '14 at 20:12
  • 2
    Thankfully there is no equivalent of this in perl, it seems like an awful thing to inflict upon a language. If you explain what you're trying to do instead of how you're trying to do it, someone here might be able to help you to a better solution (probably involving hashes). – AKHolland Sep 23 '14 at 20:19
  • If you're simply looking to import/export variables, you may want to have a look at this answer: http://stackoverflow.com/questions/4543934/how-to-share-export-a-global-variable-between-two-different-perl-scripts – AndrewPK Sep 23 '14 at 20:27
  • The requirements ended up changing and this was no longer necessary. The situation was that I was instantiating dynamic variables inside a subroutine and was planning to use those inside a template. It's really just a style preference but I wanted to pass them as an array of key/value pairs via "my $template_vars = compact("one","two","three");" instead of individual parameters. The requirements changed a bit so I'm no longer going this route. I find this function useful in PHP though so was looking for something similar. – dooplenty Oct 06 '14 at 19:01

2 Answers2

1

Instead of:

my $one = "1";
my $two = "2";
my $three = "3";

#using compact as example here since this function doesn't exist in perl
my $array = compact("one","two","three");

probably you want:

use strict;
use warnings;
use feature 'say';
use Data::Dumper;

my $numbers = {
    one => 1,
    two => 2,
    three => 3,
};

say Dumper $numbers;
my $sum = $numbers->{one} + $numbers->{two};
say $sum;
clt60
  • 62,119
  • 17
  • 107
  • 194
0

If the variables are declared as package variables (e.g. $::one = 1 or our $one = 1) then it's possible to do this by inspecting the symbol table. However, I would strongly recommend against it. I've been programming Perl for over 20 years and I've never once had to do this. Use a hash from the get-go instead.

Please, please don't do this. But if you are in a jam and truly hard up for a solution, here's one. It will only work for simple scalar values (as in your example) declared as package variables.

my %hash = map { $_ => ${$::{$_}} } qw{one two three};

Or:

sub compact { +{ map { $_ => ${$::{$_}} } @_ } }

my $hashref = compact("one", "two", "three");
mwp
  • 8,217
  • 20
  • 26