in reply to Re: Need help figuring out how to order/eval the numbers
in thread Need help figuring out how to order/eval the numbers

thank you...I will follow the FH open and close within their scope...I liked that and clear to me now and looks elegant.also, I like your way of IF structures...mine still looks too childish

I have a few question on somethings you did here, please help me understand. I am reading on this now too.

what is the ? do here?

my $fh = defined $hash{$ita}[0] && defined $hash{$ita}[1] ? $out : $out1;

hmm, what is in the sort_italian() at start? and why () and not square brackets?

confused on hash_ref which uses square and now parenthesis

for my $ita (sort { sort_italian() } keys %hash)

map...nice function, I'm geeking out on map right now. but what is the () mean? is this NOT a hash_ref then??as per your comment, $_ is the value of the keys being check for UNDEF values , I understand that but not ()

print $fh "$ita => ", join(',', map { $_ // () } @{ $hash{$ita} }), "\n";

I have problems following the error checking. what is this statement saying here?         return $numbers{$a} <=> $numbers{$b};

Replies are listed 'Best First'.
Re^3: Need help figuring out how to order/eval the numbers
by Athanasius (Archbishop) on Jun 23, 2015 at 07:52 UTC

    Hello again perlynewby,

    It seems that, between aaron_baugher’s excellent replies and your own further reading, you already have answers to most of your questions. I will just comment on this part of my code:

    my $fh = defined $hash{$ita}[0] && defined $hash{$ita}[1] ? $out : $out1; print $fh "$ita => ", join(',', map { $_ // () } @{ $hash{$ita} }), "\n";

    The ... ? ... : ... construct is the conditional, or ternary, operator, which is documented here. I use it to select which of two filehandles will be written to by the following print statement. This is an example of applying the DRY (“don’t repeat yourself”) principle by changing the original two parallel print statements into a single statement. The advantage here is that if the statement is later changed (see below!), there is no danger of updating one statement and overlooking the other in the process.

    The expression { $_ // () } uses the Logical Defined-Or operator to select the empty parentheses — () — only if the current value ($_) is undefined. Empty parentheses are used because they represent an empty list, and interpolating an empty list into a second list has no effect on that second list. Any other value here — e.g. undef, "" (the empty string), [] (which is a reference to an empty anonymous array) — would add something unwanted to the second list, because in each case the value is a scalar which is added as a new list element. The following should make this a little clearer:

    17:42 >perl -MData::Dump -wE "my @c = qw(a e i o u); @c = map { $_ eq +'i' ? undef : $_ } @c; dd \@c;" ["a", "e", undef, "o", "u"] 17:44 >perl -MData::Dump -wE "my @c = qw(a e i o u); @c = map { $_ eq +'i' ? () : $_ } @c; dd \@c;" ["a", "e", "o", "u"] 17:44 >
    map...nice function, I'm geeking out on map right now.

    Yor’re right! Unfortunately, map was the wrong function to use here. :-( I should have used grep:

    print $fh "$ita => ", join(',', grep { defined } @{ $hash{$ita} }), "\n";

    — much more straightforward. D’oh!

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      excellent! I liked the break down of the expression...I totally had some of this wrong in my head

      this explanations were very insightful and removed misconception that I may have had...that's not to say I will get it right on my next try(s) to modify/learn perl code.

      will think of a program to use what I have learn from you...or you can provide me with an idea to utilize these new learnings too...and so expect a little more questions

      again Grazie MILLE

      I am now stopped with my new test to implement new learnings...I read and reviewed other code and still lost...maybe I need a break or think of a better test prog to try out skills

      need help here with doing a proper sub routine check on the values of a hash ref. while using the <=>

      IF the value = value1 then print out to file

      IF value of either is not the same then print those to a file

      1 = 1 2 = 2 3 = 3 4 = 4 5 = 5
      1 = 2 2 = 2 3 = 4 4 = 7 5 = 5 6 = 6
      use strict; use warnings; use autodie; use diagnostics; use Data::Dump qw(dump); my %seen; open my $in,'<','./Test_Data.txt'; while(<$in>){ my ($key,$value)= split /[\s=\s]+/; $seen{$key}[0]=$value; } close $in; #using ONE hashes to check key open my $in1,'<','./Test_Data1.txt'; while(<$in1>){ my ($key,$value)= split /[\s=\s]+/; $seen{$key}[1]=$value if (exists $seen{$key}); } close $in1; #dump \%seen; #section uses as follows: ? conditional to write on different output f +iles #also, 1st sub to written by me... to check the values open my $out,'>','./OUT_test_data_keys_and_sorted_values_match.txt'; open my $out1,'>','./OUT_test_data_No_values_matched.txt'; foreach my $key ( sort { check_values()} keys %seen){ if ($key){ my $fh = defined $seen{$key}[0] && defined $seen{$key}[1] ? $out:$out1; print $fh "$key => ",join(',',@{$seen{$key}}),"\n"; } } close $out; close $out1; #here is first SUBROUTINE checks that value [0] == value[1] #my %number; sub check_values{ for my $key (sort {$a<=>$b} keys %seen){ #don't know how ,where to get valueat [0],value at[1] from??wh +o has the values? what is really (a and b) in, is it $_ or %seen? wha +t am I really evaluating with,is it like this: $seen{$key}[0]=$a or $ +seen{$key}[1]=$b...completely lost... }

        perlnewby:

        The function you give sort has one job: to tell sort which order you want between two items: $a and $b. If you want the value in $a to sort after the value in $b, your function needs to return 1. If you want it to sort before $b, return -1.

        So you don't need to figure out how to get the values, they're handed to you as $a and $b. You simply need to tell sort how to decide which order you want for any two values.

        $ cat foo.pl use strict; use warnings; my @list = (qw(now is the time)); sub compare { my ($left, $right) = @_; print "Comparing $left and $right.\n"; return 1 if $left gt $right; return -1 if $left lt $right; return 0; } print "BEFORE: ", join(" ", @list), "!\n"; @list = sort { compare($a,$b) } @list; print "AFTER: ", join(" ", @list), "?\n"; $ perl foo.pl BEFORE: now is the time! Comparing now and is. Comparing the and time. Comparing is and the. Comparing the and now. AFTER: is now the time?

        Update: Added punctuation for a bit of fun...

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

        I have written little test code that test out the order of the hash BUT ,out of curiosity, I want to call it from this little test program I've been bugging you about, can this be done? and how? I'd appreciate a pointer to read up on it and then I will try it out...I may have questions later but I want to read this first.

Re^3: Need help figuring out how to order/eval the numbers
by perlynewby (Scribe) on Jun 22, 2015 at 23:31 UTC

    ok, I read about most of my questions and I think I understand them some but I still have an issue with understanding the error check portion here. don't know what this does

    return $numbers{$a} <=> $numbers{$b}; #I guess it's checking against e +achother...but how? is this a subroutine somewhere in a library/modul +e??

    after reading, this is still a little vague. I have issues understanding when to use the [] vs (). any clarification will be appreciated.

    $hash{$ita}[0]=$spa; #here we assign has_ref $span value address to fi +rst position in array for my $ita (sort { sort_italian() } keys %hash) #here ?? adding value + to array? am I right? not sure...

      That's not error checking. His comment meant that you should add error checking there, to make sure the values being compared exist and are numbers, for instance.

      The <=> operator (search for it in perlop) compares two numbers and returns -1 if the left argument is less than the right one, 0 if they are equal, and +1 if the left argument is greater than the right. It's very commonly used in sort routines, since sort then uses those -1/0/+1 return values to decide which of two values should come first. The way sort works (simplistic explanation coming) is by comparing values in the list to each other, two at a time, and swapping them if they're out of order, and continuing until the entire list is sorted. The subroutine or block you provide as the sort routine is what it uses to compare the two values, which are passed to that routine as $a and $b.

      So he's having sort call sort_italian() to do the comparisons, and it uses the <=> operator to compare the values numerically.

      Aaron B.
      Available for small or large Perl jobs and *nix system administration; see my home node.

        Ahh, Thank you Aaron for your well explained comments/insights.

        darn, I couldn't find a section to read about the <=> thingy...In fact, I didn't know what to look for...I'm too new to know what that means or search for that thingy in my book I got from library.

        reading on this tonight so tomorrow may have more questions

      for my $ita (sort { sort_italian() } keys %hash) { # loop code goes here }

      Here's what the code above does.

      1. First, keys gets all the keys from the hash, in no particular order, and passes them to its left as a list.
      2. sort then sorts that list based on the comparison found in the subroutine sort_italian(), and passes the now-sorted list of keys to its left.
      3. 'for' points the variable $ita at the first value on that sorted list, and runs the code in the enclosing braces following it (where I've replaced the code with a comment above). After that block is finished, for points $ita at the second item on the list and runs the block again, then runs it with $ita pointed at the third item, and so on until the list is exhausted or a command inside the block stops it (like last, for instance).

      See perlsyn for more info on the for (also known as foreach) operator. See the section "Foreach Loops" there; stay away from the C-style loops described in the "For Loops" section unless you know you need one.

      Aaron B.
      Available for small or large Perl jobs and *nix system administration; see my home node.