CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Naming an array from a string?

 



chrisabrooks
Novice

Dec 18, 2000, 2:38 PM

Post #1 of 10 (821 views)
Naming an array from a string? Can't Post

Is it possible to name an array from the value in a string? Basically, I want something like this to happen:

@$_[0] = "blah, blah, blah";

Where the array is given the name by the value in $_[0]. I've tried quotation marks in every possible place I couldm, I've read the dreaded perldocs, I've... Well... Screamed at myself a few times, so now I'm asking you Smile Is it possible in the current version of perl?



Rivotti
User

Dec 18, 2000, 5:32 PM

Post #2 of 10 (817 views)
Re: Naming an array from a string? [In reply to] Can't Post

Hi chrisabrooks,

I'm not sure if this is a good way to do it but itīs possible

# give to a variable the value you want
$array = '@'.$_[0]; # if $_[0] is eq to "exp" $array woulb be eq to @exp

# Now use eval
eval($array);

There some cautions you have to make with the eval function so be careful when using it

Rivotti




japhy
Enthusiast

Dec 18, 2000, 9:04 PM

Post #3 of 10 (815 views)
Re: Naming an array from a string? [In reply to] Can't Post

You are asking to use symbolic references:


Code
$name = "foobar"; 
@$name = qw( ABC DEF );
# @foobar = qw( ABC DEF );

Please do not use symbolic references. They are useful in one specific place, and that is all. Please use real hard references. It sounds like you want a hash of array references:


Code
$name = "foobar"; 
$HoA{$name} = [qw( ABC DEF )];
print $HoA{$name}[1]; # "DEF"

I suggest you read perldoc perlreftut and perldoc perlref.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


chrisabrooks
Novice

Dec 19, 2000, 1:33 PM

Post #4 of 10 (811 views)
Re: Naming an array from a string? [In reply to] Can't Post

Thanks, Rivotti, that's perfect!

Japhy, The was I explained it looked like I meant symbolic referances, but I didn't... Should have explained myself a bit better, I suppose! Anyway, thanks! Smile



japhy
Enthusiast

Dec 19, 2000, 2:48 PM

Post #5 of 10 (809 views)
Re: Naming an array from a string? [In reply to] Can't Post

You're constructing a variable's name from the value of another variable -- that's what a symbolic reference is. You should try to avoid them.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


chrisabrooks
Novice

Dec 20, 2000, 1:33 PM

Post #6 of 10 (801 views)
Re: Naming an array from a string? [In reply to] Can't Post

OK, read those perldocs... What's so bad about them? I only need it in one place - it's in a subroutine that opens a file depending on the variables passed to it. I only need to use them because there is no other way for the subroutine to know what array to assign the information in the file to. After the subroutine has ended, the real @whatever's are used - of course, because that part of the code knows what array it just made via the subroutine. Is there a better way to do this? Before I had the file opening the long way, every single time it opened, in every single place in the script. I use the subroutine, and it shaves about 10K off! Naturally, the less space it takes up, the better, as this is a frequently downloaded script (in zip format), so the less the load on the server from downloads of it, the better!



japhy
Enthusiast

Dec 21, 2000, 6:59 AM

Post #7 of 10 (792 views)
Re: Naming an array from a string? [In reply to] Can't Post

Mark-Jason Dominus wrote a three-part article on why using a variable's value as a variable's name is silly. It starts here.

What I would suggest in your case? A hash of arrays. The keys of the hash are the filenames, and the arrays are the content of the file (if you really need to store the file's content in an array, which is something you should also try to avoid).


Code
open FILE, $somefile or die "can't read $somefile: $!"; 
@{ $content{$somefile} } = <FILE>;
close FILE;

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author


chrisabrooks
Novice

Dec 21, 2000, 1:48 PM

Post #8 of 10 (788 views)
Re: Naming an array from a string? [In reply to] Can't Post

Thanks, I'll give that a read! Smile



chrisabrooks
Novice

Dec 21, 2000, 2:26 PM

Post #9 of 10 (787 views)
Re: Naming an array from a string? [In reply to] Can't Post

OK, I see the total mess you can get into with them now. Here's the code now:

In main part of file, replicated numerous times, with different values in each for the file name and the filehandle.
&op("settings.txt", "SETTINGS");
@SETTINGS = @THEFILE;

The subroutine at the end:
sub op {
system("chmod 777 $_[0]");
open("$_[1]","$_[0]");
$file = '<'.$_[1].'>';
@THEFILE = eval($file);
close("$_[1]");
system("chmod 000 $_[0]");
}

Is this a better way to do it? Assign the data in the file to a temporary array than back in the main part of the code assign the data in the temporary array into the array I actually want? (BTW, I know it's inelegant to use a system command for chmodding!) This still saves a lot of KB's!




japhy
Enthusiast

Dec 22, 2000, 7:13 AM

Post #10 of 10 (783 views)
Re: Naming an array from a string? [In reply to] Can't Post

You suffer from "stringification", a common ailment resulting in the possibly dangerous (I kid you not) quoting of variables when they needn't or shouldn't be quoted. See my article for The Perl Journal for information on this affliction.

I'd now like to comment on the code. The op() function has no need to send the name of a filehandle, does it? The filehandle gets used locally (and closed), so it doesn't need to be sent. And the reason you need to call eval() in that function is because doing <$foo> works, but doing <$foo{bar}> doesn't work. You could call the function readline(), instead, but I think you're going about this in a rather roundabout manner.


Code
# $contents is a reference to an array 
# $contents->[0] is the first element, etc.
$contents = op("setting.txt");

sub op {
my $filename = shift;
my @data;
local *FH;

chmod 0777, $filename; # WHY?!
open FH, $filename;
@data = <FH>;
close FH;
chmod 0000, $filename; # WHY?!

return \@data;
}

I have to ask why you chmod() the file to 0777! This is quite unsafe, since this allows ANYONE to mess with the file in the small amount of time you give them. Perhaps the file should be kept at 0700 all the time, which allows only the owner of the program to access the file.

Hmm, what else... oh, it is generally poor practice for a function to modify or create global variables. It's far better for the function to RETURN a value, which you then assign to a global variable. You see, it's very easy to accidentally overwrite a variable, if you just start using globals everywhere.


Code
for ($i = 0; $i < 10; $i++) { 
print "$i = ";
function($i);
print "\n";
}

sub function {
my $x = shift;
for ($i = $x; $i > 0; $i--) {
print "$i, ";
}
print "\n";
}

Do you see the problem? I use $i in the function, and since it's not localized, I've just screwed up the $i in the loop outside the function. So variables in functions should be declared with my, which makes them localized.

Other miscellaneous (important) comments -- you should really endeavor to write your programs to work under the -w switch and the use strict pragma. -w will warn you of possible mistakes you've made, and use strict will probably seem like you're not allowed to do ANYTHING -- but it's there to make sure you're doing everything safely, like declaring ALL your variables (so that typos don't happen) and using hard references only, etc.

Jeff "japhy" Pinyan -- accomplished hacker, teacher, lecturer, and author

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives