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

I am trying to use join in the below snip of code, but I can not seem to find the correct way to work it in. I have looked at the perldocs and can't find this type of situation. Can it be done? I would like the results to be returned seperated by ':' I tried
print ref join (":", $searchresult)
What ends up happening is that none of the results are printed at all. I would greatly appreciate some help. Here is the entire print statement:
print ref $searchresult ? "Located Part Number: @{ $searchresult }\n" : "Your Part Number ($part) Rev ($rev) could not be found....\n";
Kerry
"Yet what are all such gaieties to me
Whose thoughts are full of indices and surds?"
quotes the Lama

Replies are listed 'Best First'.
Re: using join with a print ref statement
by dpuu (Chaplain) on Jan 20, 2003 at 17:49 UTC
    The ref function applies to its arg. In this case, the C<join> is passing a string to C<ref>: which returns a null (undef) value. So nothing is printed.

    You probably want something like:

    print join(":", @$result) if ref $result;
    If you wish to use the ?: notations, then
    print ref($result) ? join(":", @$result) : "no results";
    --Dave

    Update: "?:" example fixed per ihb's response

      print (ref $result) ? (join ":", @$result) : "no results";

      "I looks like a function, hence it is a function." That will parse as   (print(ref $result)) ? (join ":", @$result) : "no results"; You need to disambiguate with a +:   print +(ref $result) ? (join ":", @$result) : "no results"; But I don't understand what's wrong with   print ref($result) ? (join ":", @$result) : "no results"; or for that matter,   print ref $result ? (join ":", @$result) : "no results"; either. Since that will actually parse the intended way.

      ihb
        Duh! You're right, I was careless. --Dave
(jeffa) Re: using join with a print ref statement
by jeffa (Bishop) on Jan 20, 2003 at 17:55 UTC
    Hmmmm ... i don't like the idea of determining whether or not search results were found by using ref. If i were designing this i would create a subroutine that either returned the results in an array (or array ref) if results were found or returned undef if no results were found. This is a much simpler approach that will most likely be more robust in the long run, i'll wager. ;)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Actually, I do use a sub to return the searchresults, kind of like a hash, then I slice it. at least I think that is the terminology. The actual code is in my scratchpad. Its the best I could do with a lot of help from this site and the 3 weeks that I have been using Perl. I hope to make it a lot better as I go along. Kerry
      "Yet what are all such gaieties to me
      Whose thoughts are full of indices and surds?"
      quotes the Lama
        I modified the code on your scratchpad (here is the original for hysterical raisins): Into the following (untested) code:
        my $searchresult = search( part => $part, rev => $rev, filename => './file.db', ); print $searchresult ? "Located Part Number: @{[join ':', @$searchresult ]}\n" : "Your Part Number ($part) Rev ($rev) could not be found....\n" ; sub search { my %args = @_; my $found = 0; my @record; open PARTS_DB, $args{filename} or die "$args{filename}: $!"; while (!$found and my $record = <PARTS_DB>) { chomp $record; @record = split /\|/, $record; if ($record[PART] eq $args{part} && $record[REV] eq $args{rev}){ $found = 1; last; } } close PARTS_DB; return $found ? \@record : undef; }
        This should have the same results as your version, but i think my version is a bit more clear on the intent.

        UPDATE:
        On another note, if the array is not going to be considerably large, then consider returning the array a list instead of a reference to the array:

        sub search { ... yadda yadda yadda ... return @record; } my @searchresult = search(... yadda yadda ...); print @searchresult ? "got it: @searchresult\n" : "nadda\n";
        much simpler, but not very good if @record is going to be large.

        UPDATE x 2
        Sorry about that, change the && to and on line 38 (i told you this was untested ;)). Actually, you could remove the check for !$found all-together (untested and unplanned! ;)):
        while (my $record = <DATA>) {

        or you could remove the last statement (not the last statement ;)). The other errors are cut and paste errors on your behalf due to code wrapping on this site. Try it now. ;)

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: using join with a print ref statement
by pfaut (Priest) on Jan 20, 2003 at 17:49 UTC

    Are you trying to use ref as a filehandle? If so, your code is probably not being parsed the way you think it is since ref is a perl built-in function

    What exactly is in $searchlist?

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
Re: using join with a print ref statement
by Hofmator (Curate) on Jan 20, 2003 at 17:51 UTC
    So if I get you right, $searchresult is a reference to an array. Then the following should work:
    print ref $searchresult ? "Located Part Number: @{[join ':', @$searchresult ]}\n" : "Your Part Number ($part) Rev ($rev) could not be found....\n"; # or local $" = ':'; print ref $searchresult ? "Located Part Number: @{ $searchresult }\n" : "Your Part Number ($part) Rev ($rev) could not be found....\n";

    -- Hofmator

      The first suggestion worked. I was way off in my attempts. I figured that 'join' had to come earlier in the statement. Thanks very much for the help Kerry
      "Yet what are all such gaieties to me
      Whose thoughts are full of indices and surds?"
      quotes the Lama
Re: using join with a print ref statement
by diotalevi (Canon) on Jan 20, 2003 at 18:29 UTC

    I originally wrote this for Bismark at http://www.greentechnologist.org/wiki/wiki?Bismark which was a quick fix-up of some pre-existing code currently viewable on Bismark's scratchpad (I've asked Bismark to post the code in response to this so the context can be retained). The idea was print TRIGRAPH or just a fancy if/else.

    I didn't use a if/else because it's clearer this way that you're just switching between strings to print. A if/else construct would have to have two calls to print() which violates my sense of aesthetics. That ref() function is controlling the "? :" construct. So ref $searchresult is the test. The true answer comes immediately after the '?' character and then false answer comes immediately after the : character. You can't swap them though - test : true ? false is invalid. It's always test ? true : false.

    if (ref $searchresult) { print "Found it: @$searchresult\n"; } else { print "It wasn't found\n"; }

    Seeking Green geeks in Minnesota

      Sorry I could not remember your name to give you more credit for the help you gave me. I understand your code much better now than I did last week. The first code here is how I originally had it and the code below that is diotalevi's with a few minor changes. Everything works exactly as I want it to now. I understand fully that there are much more efficient ways to do this. In time..in time.
      #!/usr/bin/perl -w use strict; use Data::Dumper; use diagnostics -verbose; print "Enter the Part Number you wish to search for: "; my $part = <STDIN>; chomp($part); print "Enter the Revison for ($part): "; my $rev = <STDIN>; chomp($rev); my $searchresult = &search(part => "$part", rev => "$rev"); if (defined $searchresult) { print "Located Part Number $part: @$searchresult[1 .. 7]\n"; }else { print "Your Part Number ($part) Rev ($rev) could not be found...\n +"; } # This routine will accept a part number as an anonymous # hash, and search thru a text file returning the entire # record (pipe delineated) of the 1st occurence sub search { my %args = @_; my $retval; local *FH; open (FH, './fai.txt') || die "Cannot open file: ($!)"; my @records = <FH>; chomp (@records); foreach my $line (@records){ my @fields = split(/\|/, $line); if ($args{part} eq $fields[0] && $args{rev} eq $fields[1]){ $retval = \@fields; #last; } close FH; return $retval; } }
      diotalevi's code start's here:
      #!/usr/bin/perl -w use strict; use Data::Dumper; use diagnostics -verbose; use constant PART => 0; use constant REV => 1; print "Enter the Part Number you wish to search for: "; my $part = <STDIN>; chomp $part; print "Enter the Revision for ($part): "; my $rev = <STDIN>; chomp $rev; my $searchresult = search( part => $part, rev => $rev, filename => './file.db', ); print $searchresult ? "Located Part Number: @{[join ':', @$searchresult ]}\n" : "Your Part Number ($part) Rev ($rev) could not be found....\n" ; sub search { my %args = @_; my $found = 0; my @record; open PARTS_DB, $args{filename} or die "Cannot open file $args{fil +ename}: $!"; while (!$found && my $record = <PARTS_DB>) { chomp $record; @record = split /\|/, $record; if ($record[PART] eq $args{part} && $record[REV] eq $args{rev +}) { $found = 1; last; } } close PARTS_DB; return $found ? \@record : undef; }
      Kerry
      "Yet what are all such gaieties to me
      Whose thoughts are full of indices and surds?"
      quotes the Lama

        I'm almost positive that I didn't write it exactly like that because I almost never write not as an exclamation mark. Anyhow, you could omit that $found value because your last skips right out of the while. The other use you use for $found is irritating. I much prefer setting the return value explicitly and letting that take the place of $found. I copied my code, fixed it up and commented the changes.

        sub search { my %args = @_; # Turned into a scalar. An array reference will be # stored here if the value being searched for was # found. my $return_record; local *PARTS_DB; open PARTS_DB, $args{filename} or die "Cannot open file $args{fil +ename}: $!"; while (my $record = <PARTS_DB>) { chomp $record; my @record = split /\|/, $record; next unless $record[PART] eq $args{part} and $record[REV] eq $args{rev}; # Change this from assigning to @return_record # so now it's an array reference. Also add a last; # call; $return_record = \ @record; last; } close PARTS_DB or die "Can't close PARTS_DB $args{filename}: $!"; # This returns whatever was found which may be nothing return $return_record; }

        Seeking Green geeks in Minnesota