Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Re: Dynamically allocating variables

by newatperl (Acolyte)
on Dec 02, 2001 at 05:36 UTC ( [id://128945]=note: print w/replies, xml ) Need Help??


in reply to Re: Dynamically allocating variables
in thread Dynamically allocating variables

I'm using the stucts from Class::Struct, can I get away with just defining one struct and then reusing that struct over and over for each line? i.e. I guess my real question is, when you push something onto a Hash, does it push the value, or just a pointer? Hence, if I reuse the same struct, and the Hash just had pointers, I'd be overwriting the previous variables... Thanks.
  • Comment on Re: Re: Dynamically allocating variables

Replies are listed 'Best First'.
Re: Re: Re: Dynamically allocating variables
by Fastolfe (Vicar) on Dec 02, 2001 at 06:04 UTC

    does it push the value, or just a pointer?

    When you're passing around objects, really you're passing around special references. So even if you have two scalars pointing to one struct, it's that same struct you're modifying, regardless of how it's named.

    It might be easier to illustrate with an example:

    use Class::Struct; use strict; struct Test => [ xyz => '$' ]; our $T = new Test(xyz => 123); print "\$T->xyz starts as: ", $T->xyz, "\n"; no strict 'refs'; my $symbolic = "T"; ${$symbolic}->xyz(456); print "\$T->xyz is now: ", $T->xyz, "\n"; my %A $A{t} = $T; $A{t}->xyz(789); print "\$T->xyz is now: ", $T->xyz, "\n"; __END__ $T->xyz starts as: 123 $T->xyz is now: 456 $T->xyz is now: 789
    To get "full" copy effects, you need to make a copy of each of the fields:
    my $a = new Test ( xyz => 123 ); # original my $b = new Test ( xyz => $a->xyz ); # copy of a $b->xyz(456); printf "a=%d b=%d\n", $a->xyz, $b->xyz; # a=123 b=456

    I don't know of an easy way to "deep copy" struct objects, though the Clone module (or Storable's 'dclone' function) may help.

      Thanks for clarifying that Fastolfe. But, I guess my original question still stands. Without turing strict off, I can't really load a Hash with unique structs that are created on the fly as I read each line in. true or not true?
        I have a feeling that you and Fastolfe are talking past each other.

        The answer is that you can. He is using anonymous hashes as structs (which is usually the right native Perl data structure to use for that, even though it is not perfect). What strict.pm stops you from doing is making the assumptions that these anonymous things have concrete names in your main namespace - names which you might accidentally use to have one of them override another. (This would be bad.)

        And I guess I just don't understand your question. Do you have Perl constructs in your input that you're trying to place into a hash? Something like this might work in that situation:
        my %data; while (<DATA>) { my ($key, $value) = eval $_ or die; $data{$key} = $value; } print $data{other_key}->[1]; # data __DATA__ some_key => { data => 'structure', number => 1 } other_key => [ qw/ other data structure / ] third_key => "and a simple third"
        Is this what you're getting at? If not, I need to see something more specific.
(jeffa) 3Re: Dynamically allocating variables
by jeffa (Bishop) on Dec 02, 2001 at 06:17 UTC
    You don't really push to a hash, you can - but push is usually reserved for array (and yes, a hash is an array). My point is that you assign a value to a hash key - that value can be a scalar (the value), a reference (the pointer), or other things.

    Here is an example that reads 'configuration info' from Perl's built in DATA filehandle. I use DATA because it's easy and you only need one file for demonstrations. Anyhow, the configuration is simply two values seperated by a comma per line. The while loop processes DATA one line at a time and creates a new struct object with the values it finds. After the struct is instantiated, it is pushed to an array. Since it is already a reference there is no need to de-reference it. The last line is a for loop that prints out only one of the attributes for each struct in the array.

    use strict; use Class::Struct; # declare the struct struct(MyStruct => { even => '$', odd => '$', }); # create array of structs my @structs; while (my $line = <DATA>) { chomp $line; my ($odd,$even) = split(',',$line); my $obj = new MyStruct; $obj->odd($odd); $obj->even($even); push(@structs,$obj); } print $_->odd(), "\n" foreach (@structs); __DATA__ one,two three,four five,six seven,eight nine,ten
    But hold it right there! Why are you using Class:Struct? No offense to the author, but if you are going to code in Perl, code like Perl. Check this out:
    use strict; # create array of structs my @structs; while (my $line = <DATA>) { chomp $line; my ($odd,$even) = split(',',$line); my %hash = ( odd => $odd, even => $even, ); # i do have to de-reference %hash though push(@structs,\%hash); } print $_->{'odd'}, "\n" foreach (@structs); __DATA__ one,two three,four five,six seven,eight nine,ten
    Same thing with less lines, and i spared using map to golf it down even further ... oh what the hell:
    print $_->{odd},"\n"for map{my($o,$e)=split',',$_;{odd=>$o,even=>$e}}< +DATA>;
    Welcome to Perl. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)
    

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://128945]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-25 04:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found