Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

what is @$varname in perl

by sandy105 (Scribe)
on Jul 03, 2014 at 08:38 UTC ( [id://1092122]=perlquestion: print w/replies, xml ) Need Help??

sandy105 has asked for the wisdom of the Perl Monks concerning the following question:

i had to write a csv sorting code for which i used the following code :

foreach(@files){ if(/\.csv$/i) { # if the filename has .csv at the end push(@csvfiles,$_); } } foreach(@csvfiles) { $csvfile=$_; open(hanr, "D:\\stock\\".$csvfile)or die"error $!\n"; open(hanw , ">D:\\stock\\sorted".$csvfile) or die"error $! \n"; @lines=(); @lines=<hanr>; foreach $line (@lines){ chomp $line; $count++; next unless $count; # skip header in csv my $row; @$row = split(/,/, $line ); push @$sheet2 , $row; } foreach my $row ( sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @$sheet2 ) { chomp $row; print hanw join (',', @$row ),"\n"; } @$sheet2 = (); $count = -1; close(hanw); close(hanr); }

however i do not understand what @$row is ..also i understand sorting a NORMAL array @sheet2 comparing coulumn 0 and 1 ..but i cannot understand what is the state of @$row and $ row being pushed into @$sheet2; if someone would explain the whole thing it would be wonderful:

@$row = split(/,/, $line ); push @$sheet2 , $row; } foreach my $row ( sort {$a->[0] cmp $b->[0] || $a->[1] cmp $b->[1]} @ +$sheet2 ) { *print hanw join (',', @$row ),"\n"; }

Replies are listed 'Best First'.
Re: what is @$varname in perl
by choroba (Cardinal) on Jul 03, 2014 at 08:52 UTC
    Crossposted at StackOverflow. It is considered polite to inform about crossposting so people not attending both sites don't waste their time hacking a problem already solved at the other end of the Internet.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      sorry i will keep in mind . i am new to perl and perlmonks, i have worked in java,web developement only before.

        The convention is not specific to PerlMonks nor to Perl. It is basic politeness to inform the readers of any forum that you have solicited responses in other places as well so that the readers do not waste their valuable time presenting solutions which have already been discussed elsewhere.

        So, other than PerlMonks and SO, where else have you asked this question?

Re: what is @$varname in perl
by AppleFritter (Vicar) on Jul 03, 2014 at 09:13 UTC

    $row is an array reference (sort of like a pointer in C); @$row is the actual (anonymous) array it references. The same goes for $sheet2 and @$sheet2.

    What the code is essentially doing is to read each file line by line, split each line along commas, and store everythign in an array of arrays. So, for instance, the following file:

    Name,Level,Writeups,XP Corion,Pope (28),8574,108561 Grandfather,Cardinal (24),6205,67751 Athanasius,Prior (17),773,11777 AppleFritter,Pilgrim (8),92,784

    would be turned into this data structure:

    $VAR1 = [ [ 'Corion', 'Pope (28)', '8574', '108561' ], [ 'Grandfather', 'Cardinal (24)', '6205', '67751' ], [ 'Athanasius', 'Prior (17)', '773', '11777' ], [ 'AppleFritter', 'Pilgrim (8)', '92', '784' ] ];

    This is then used to sort the file on the first two columns.

      thank you but its still not clear, so @{$row} contains that data structure and @{$sheet2} is pushed $row the reference . i was reading into undefined and reference but still am confused ..refrences are declared like this i saw . could you take out time and give clarity to the undefined $row ,@$row , and what $row being pushed to @$sheet2 means

      my @array = (1, 2, 3, 'four'); my $reference = \@array;

        I'm not entirely sure what your question is, or where the confusion lies. Could you clarify?

        As I said above, references are sort of like pointers in C, if you're familiar with that. A data structure lives somewhere in memory; another variable, a scalar (which might in turn be an element of an array or hash, of course) holds a reference to it. A redirect, if you will: "the data you're looking for is found in another location. Walk this way!"

        Programming Perl has an entire chapter on references, so if you've got that book, I'd read that. (If you don't have that book, buy it, it's a must-have for any Perl programmer.) Also, see perlref for a less gentle introduction.

        Anyhow, to sum it up:

        • $row contains (colloquially: is) a reference to an array, i.e. the one that split returns.
        • That array does not have a name of its own; i.e., it's not @array or any such thing.
        • However, you can use the reference in $row -- "walk this way", as it were, following the directions it contains -- by dereferencing the reference. For an array reference, this is done by adding the array sigil, @: @$row.
        • The same applies to $sheet2 and @$sheet2.
        • Finally, @$sheet2 -- an array, remember! -- is used to store a list of references, each of which points to another array: one for each row.

        So you have something like this for each line:

        $row @$row +---+ +-----+-----+-----+-- | *-----> | ... | ... | ... | ... +---+ +-----+-----+-----+--

        and something like this for the entire file:

        $sheet2 @$sheet2 (each of the @$row's) +---+ +---+ | | +-----+-----+-----+-- | *-----> | *-----> | ... | ... | ... | ... +---+ | | +-----+-----+-----+-- +---+ | | +-----+-----+-----+-- | *-----> | ... | ... | ... | ... | | +-----+-----+-----+-- +---+ | . | .

        Does that make it clearer?

Re: what is @$varname in perl
by perlfan (Vicar) on Jul 03, 2014 at 11:34 UTC
    It seems like you're writing your arrays as array references just so you can avoid creating a reference out of a non-reference.

    You have:

    foreach $line (@lines){ chomp $line; $count++; next unless $count; # skip header in csv my $row; @$row = split(/,/, $line ); push @$sheet2 , $row; }
    But if you ask me, it'd be tons more clear if you did this:
    my @sheet2 = () # .... foreach $line (@lines){ chomp $line; $count++; next unless $count; # skip header in csv my @row = (); @row = split(/,/, $line ); push @sheet2 , \@row; }
    Another example is:
    @$sheet2 = ();
    Should be:
    @sheet2 = ();
    or
    $sheet2 = [];
    It seems to me you're conflating scalars, arrays, and references. Cleaning up the code and being consistent will go a long way in dispelling your confusion.

      i read up on reference and understand a scalar is assigned as reference :

      my @array = (1, 2, 3, 'four'); my $reference = \@array;

      i modified using your suggestion as below

      foreach $line (@lines){ chomp $line; $count++; next unless $count; my @row = (); @row = split(/,/, $line ); push @sheet2 , \@row; } foreach my $row ( sort {$a->[0] cmp $b->[0] || $a->[1] cmp $b- +>[1]} @sheet2 ) #sorting based on date ,then stockcode { chomp $row; print hanw join (',', @$row ),"\n"; }

      then why assign @sheet2 as reference

        this :

        ... my $row; @$row = split(/,/, $line ); push @$sheet2 , $row; ...
        OR
        ... my @row = (); @row = split(/,/, $line ); push @sheet2 , \@row; ...
        Could be written like this in one line instead of three
        ... push @sheet2, [ split(/,/, $line ) ]; ...
        And there is no need for the array variable row at all.
        You could use Data::Dumper to view your variable @sheet2 to confirm.

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
        push @sheet2 , \@row;
        You're pushing a reference to @row as an item into @sheet2. In order to create complex data structures (array of arrays, array of hashes, etc) you need to assign references.
Re: what is @$varname in perl
by Anonymous Monk on Jul 03, 2014 at 09:00 UTC
    $ ppi_dumper 2
    PPI::Document
      PPI::Statement
        PPI::Token::Cast    '@'
        PPI::Token::Symbol          '$sheet2'
      PPI::Token::Whitespace        '\n'
    
    See perldoc PPI::Token::Cast :P
Re: what is @$varname in perl
by 2teez (Vicar) on Jul 03, 2014 at 10:06 UTC

    Hi sandy105,

    ..however i do not understand what @$row is.. and YET you had the code above written? That doesn't add up for me.

    More so, if you have to deal with CSV files, think of using either Text::CSV_XS or Text::CSV than hand-picking commas using split and others.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me

      @$row is a short way of saying:

      my @arr = split(/,/, $line ); my $row = \@arr;
      Regards,

        Please could your answer be directed to the OP not me. Thanks

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me

      "i had to write a csv sorting code for which i used the following code :"

      i wrote this multithreaded program to sort files in parallel ,this was actually the subroutine part (sort of).initial code which i tried would append sorted line to previous line, so 2 lines would be clubbed in 1 line ; hence i found THIS code on net

      initial code below

      foreach(@csvfiles) { $csvfile=$_; open(hanr,"D:\\stock\\".$csvfile) or die"error read $!\n"; open(hanw,">D:\\stock\\sorted".$csvfile) or die"error write $!\n"; @lines = (); @lines = <hanr>; shift(@lines);#remove header csv @sorted = sort multisort @lines; sub multisort { ($field1a, $field2a, $field3a)=split(/\,/, $a); ($field1b, $field2b, $field3b)=split(/\,/, $b); $field1a cmp $field1b or $field2a cmp $field2b; } print hanw @sorted; close(hanw); close(hanr); }

        Well, the above code makes sense. Maybe it is not very efficient because it splits lines inside of the sort, but it should work.

        It looks like you don't know perl, so it is bad idea to write in perl when you don't know it. So either learn it, or ask someone to write the code that you need. For that, specify exactly what the code should do.

        It's just hard to answer random questions about perl, when the listener does not know much about it. Without ground knowledge the answers won't make sense.

Re: what is @$varname in perl
by Myrddin Wyllt (Hermit) on Jul 03, 2014 at 14:37 UTC

    Not directly related to the reference / dereference question, but if your csv files do have header rows, your check on $count won't skip them, as you increment before you test (so $count will always be true). If you need to skip the headers, make $count local to the file loop (rather than global), and increment after the test.

      i have declared $count = -1 initially , so it does work

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1092122]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-03-29 10:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found