Code Comments
Programming Forum and web based access to our favorite programming groups.I am working a script that is a solution to a problem in Intermediate
Perl. Here is the script:
#!/usr/bin/perl -w
use strict;
sub check_items_for_all {
my $all_ref = @_;
my @who = keys %$all_ref;
my @required = qw(preserver sunscreen water_bottle jacket);
my @missing = ( );
for my $crew (@who){
for my $item(@required){
unless (grep $item eq $_, %$all_ref{$crew}) {
print "$crew is missing $item.\n";
#push @missing, $item;
}
}
}
#if (@missing) {
# print "Adding @missing to @$items for $who.\n";
# push @$items, @missing;
#}
}
my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
my %all = (
Gilligan => \@gilligan,
Skipper => \@skipper,
Professor => \@professor,
);
check_items_for_all(\%all);
When I run the script, I get the following error message:
syntax error at required_items.pl line 13, near "$all_ref{"
syntax error at required_items.pl line 18, near "}"
I'm not sure what is causing this. Eventually, I want the script to
access each crew member's belongings, figure out which of the items in
the @required array are missing, and place those items in the member's
array. Any hints?
Post Follow-up to this messageOn 8/22/07, Chris <cspears2002@yahoo.com> wrote:
> I am working a script that is a solution to a problem in Intermediate
> Perl. Here is the script:
>
> #!/usr/bin/perl -w
> use strict;
>
> sub check_items_for_all {
> my $all_ref = @_;
> my @who = keys %$all_ref;
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @missing = ( );
>
> for my $crew (@who){
> for my $item(@required){
> unless (grep $item eq $_, %$all_ref{$crew}) {
> print "$crew is missing $item.\n";
> #push @missing, $item;
> }
> }
> }
>
> #if (@missing) {
> # print "Adding @missing to @$items for $who.\n";
> # push @$items, @missing;
> #}
> }
>
> my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
>
> my %all = (
> Gilligan => \@gilligan,
> Skipper => \@skipper,
> Professor => \@professor,
> );
>
> check_items_for_all(\%all);
>
> When I run the script, I get the following error message:
> syntax error at required_items.pl line 13, near "$all_ref{"
> syntax error at required_items.pl line 18, near "}"
>
> I'm not sure what is causing this. Eventually, I want the script to
> access each crew member's belongings, figure out which of the items in
> the @required array are missing, and place those items in the member's
> array. Any hints?
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/
>
>
>
http://perldoc.perl.org/functions/grep.html
Without testing the code or anything, could it be that:
> unless (grep $item eq $_, %$all_ref{$crew}) {
should be:
unless (grep $item eq %$all_ref{$crew}) {
?
Post Follow-up to this message>>>>> "Y" == Yitzle <yitzle@users.sourceforge.net> writes:
Y> On 8/22/07, Chris <cspears2002@yahoo.com> wrote:
that is a bug. it assigns the number of elements in @_ to $all_ref.
that assumes $all_ref will be a hash ref.
that line is the bug and it has nothing to do with grep. you seem to
want to dereference $all_ref and look up an element. but you also deref
it as a whole hash (the %). and the hash lookup is for a hash and not a
hash ref. use $all_ref->{$crew}.
read perldoc perlreftut before you code anymore with refs.
Y> http://perldoc.perl.org/functions/grep.html
Y> Without testing the code or anything, could it be that:
Y> should be:
Y> unless (grep $item eq %$all_ref{$crew}) {
i followed up here because that answer is way wrong. the perl error
showed where the problem is and didn't mention grep at all. and your
rewrite of the grep is wrong as well.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- [url]http://www.stemsystems.com[/url
]
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding
-
Search or Offer Perl Jobs ---------------------------- [url]http://jobs.perl.org[/url
]
Post Follow-up to this messageHello Chris,
Wednesday, August 22, 2007, 7:44:02 AM, you wrote:
> I am working a script that is a solution to a problem in Intermediate
> Perl. Here is the script:
> #!/usr/bin/perl -w
> use strict;
> sub check_items_for_all {
> my $all_ref = @_;
here is the first err: you should have smthing like
my ($all_ref) = @_;
or
my $all_ref = shift @_;
> my @who = keys %$all_ref;
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @missing = ( );
> for my $crew (@who){
> for my $item(@required){
> unless (grep $item eq $_, %$all_ref{$crew}) {
this does the job well (I think :) )
unless (grep $item eq $_, $all_ref->{$crew}) {
> print "$crew is missing $item.\n";
> #push @missing, $item;
> }
> }
> }
> #if (@missing) {
> # print "Adding @missing to @$items for $who.\n";
> # push @$items, @missing;
> #}
> }
> my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
> my %all = (
> Gilligan => \@gilligan,
> Skipper => \@skipper,
> Professor => \@professor,
> );
> check_items_for_all(\%all);
> When I run the script, I get the following error message:
> syntax error at required_items.pl line 13, near "$all_ref{"
> syntax error at required_items.pl line 18, near "}"
> I'm not sure what is causing this. Eventually, I want the script to
> access each crew member's belongings, figure out which of the items in
> the @required array are missing, and place those items in the member's
> array. Any hints?
--
Best regards,
Alexandru mailto:amaximciuc@bitdefender.com
Post Follow-up to this messageOn Aug 22, 5:44 am, cspears2...@yahoo.com (Chris) wrote:
> my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
>
> my %all = (
> Gilligan => \@gilligan,
> Skipper => \@skipper,
> Professor => \@professor,
> );
Those three things look like sets (unordered) to me not lists
(ordered). The natural datatype in Perl to represent a set of strings
is a hash with keys but no values. Unfortunately there's no elegant
way to initialise such a structure in a single step. Here's one of the
least inelegant ways.
my %all;
@{$all{Gilligan}}{ qw(red_shirt hat lucky_socks water_bottle) }=();
@{$all{Skipper}}{ qw(blue_shirt hat jacket preserver sunscreen) }=();
@{$all{Professor}}{ qw(sunscreen water_bottle slide_rule batteries
radio) }=();
> unless (grep $item eq $_, %$all_ref{$crew}) {
> print "$crew is missing $item.\n";
> }
Using hashes this (which as has been point out elsewhere was wrong
anyhow) becomes:
unless ( exists $all_ref->{$crew}{$item} ) {
print "$crew is missing $item.\n";
}
Look ma, no loop.
But!... see my next reply
Post Follow-up to this messageOn Aug 22, 5:44 am, cspears2...@yahoo.com (Chris) wrote:
> I am working a script that is a solution to a problem in Intermediate
> Perl. Here is the script:
>
> #!/usr/bin/perl -w
> use strict;
>
> sub check_items_for_all {
> my $all_ref = @_;
> my @who = keys %$all_ref;
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @missing = ( );
>
> for my $crew (@who){
> for my $item(@required){
> unless (grep $item eq $_, %$all_ref{$crew}) {
> print "$crew is missing $item.\n";
> #push @missing, $item;
> }
> }
> }
>
> #if (@missing) {
> # print "Adding @missing to @$items for $who.\n";
> # push @$items, @missing;
> #}
>
> }
You've declared @missing in the wrong scope. It should be inside the
$crew loop.
And unless it is important that the elements of @missing have the same
order as those in @required then you'd be better off doing this with a
hash.
for my $crew (@who) {
my $items = $all_ref->{$crew};
my %missing;
@missing{@required} = ();
delete @missing{@$items};
# Do stuff with keys %missing
Post Follow-up to this messageChris wrote:
> I am working a script that is a solution to a problem in Intermediate
> Perl. Here is the script:
>
> #!/usr/bin/perl -w
> use strict;
>
> sub check_items_for_all {
> my $all_ref = @_;
my $all_ref = shift @_;
> my @who = keys %$all_ref;
>
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @missing = ( );
>
> for my $crew (@who){
> for my $item(@required){
> unless (grep $item eq $_, %$all_ref{$crew}) {
unless( grep $item eq $_, @{ $all_ref->{$crew} } ){
> print "$crew is missing $item.\n";
> #push @missing, $item;
> }
> }
> }
>
> #if (@missing) {
> # print "Adding @missing to @$items for $who.\n";
> # push @$items, @missing;
> #}
> }
>
> my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
>
> my %all = (
> Gilligan => \@gilligan,
> Skipper => \@skipper,
> Professor => \@professor,
> );
>
> check_items_for_all(\%all);
>
> When I run the script, I get the following error message:
> syntax error at required_items.pl line 13, near "$all_ref{"
> syntax error at required_items.pl line 18, near "}"
>
> I'm not sure what is causing this. Eventually, I want the script to
> access each crew member's belongings, figure out which of the items in
> the @required array are missing, and place those items in the member's
> array. Any hints?
>
>
--
Just my 0.00000002 million dollars worth,
Shawn
"For the things we have to learn before we can do them, we learn by doing th
em."
Aristotle
Post Follow-up to this messageOn Aug 22, 12:44 am, cspears2...@yahoo.com (Chris) wrote:
> #!/usr/bin/perl -w
> use strict;
>
> sub check_items_for_all {
> my $all_ref = @_;
This assigns $all_ref to be the number of items in @_. I don't think
that's what you want. You are passing a reference to a hash as the
first argument. You need to get the first argument out of @_. That
means you need one of:
my $all_ref = shift;
my $all_ref = $_[0];
(depending on whether or not you want @_ destroyed in the process)
> my @who = keys %$all_ref;
> my @required = qw(preserver sunscreen water_bottle jacket);
> my @missing = ( );
>
> for my $crew (@who){
> for my $item(@required){
> unless (grep $item eq $_, %$all_ref{$crew}) {
%$all_ref{$crew} does not make sense. I don't know what you're trying
to achieve there. $all_ref is a reference to a hash whose values are
references to arrays. That is:
$all_ref ==> reference to a hash
%{$all_ref} ==> the hash $all_ref references
${$all_ref}{$crew} ==> one element of $all_ref, a reference to an
array
$all_ref->{$crew} ==> Syntactic sugar. Same thing as above.
@{$all_ref->{$crew}} ==> the array that $all_ref->{$crew} references.
The second problem (which isn't really a problem) is your syntax for
grep. There are two possible syntaxes for grep(). They are:
grep EXPR, LIST
grep BLOCK LIST
You'll note that the first one does have a comma following the
expression. The second one does not. I personally prefer the second
one, because the block syntax makes it explicit where the precedence
lies, whereas I'd be second guessing myself using the expression
syntax. So I'd rewrite your line as:
unless (grep { $item eq $_ } @{$all_ref->{$crew}} ) {
> print "$crew is missing $item.\n";
> #push @missing, $item;
> }
> }
> }
>
> #if (@missing) {
> # print "Adding @missing to @$items for $who.\n";
> # push @$items, @missing;
> #}
>
> }
>
> my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
> my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
> my @professor = qw(sunscreen water_bottle slide_rule batteries radio);
>
> my %all = (
> Gilligan => \@gilligan,
> Skipper => \@skipper,
> Professor => \@professor,
> );
>
> check_items_for_all(\%all);
>
> When I run the script, I get the following error message:
> syntax error at required_items.pl line 13, near "$all_ref{"
> syntax error at required_items.pl line 18, near "}"
99% sure those syntax errors are a result of your failed dereferencing
of $all_ref.
You should probably read up on references and multi-level structures
in Perl:
perldoc perlreftut
perldoc perllol
perldoc perldsc
Paul Lalli
Post Follow-up to this messageOn Aug 22, 1:18 am, amaximc...@bitdefender.com (Alexandru Maximciuc)
wrote:
> Wednesday, August 22, 2007, 7:44:02 AM, you wrote:
>
>
> this does the job well (I think :) )
> unless (grep $item eq $_, $all_ref->{$crew}) {
No. $all_ref->{$crew} is a reference to an array. It needs to be
dereferenced.
unless (grep $item eq $_, @{$all_ref->{$crew}}) {
Please read:
perldoc perlreftut
perldoc perllol
perldoc perldsc
Paul Lalli
Post Follow-up to this messageOn Aug 22, 12:50 am, yit...@users.sourceforge.net (Yitzle) wrote: > http://perldoc.perl.org/functions/grep.html Good advice. Irrelevant to the problem at hand, but good advice nonetheless. > Without testing the code or anything, could it be that: > unless (grep $item eq $_, %$all_ref{$crew}) { > > should be: > unless (grep $item eq %$all_ref{$crew}) { Bad advice. Very very bad advice. That makes *no* sense of any kind. Even if %$all_ref{$crew} were a valid dereference, what would make you think this suggestion was valid? Did you read the link you posted? Even if you didn't, how does comparing a scalar to a hash make any sense? How does eliminating the LIST passed to grep() make any sense? I'm sure you were trying to help, which is respectable, but really giving bad advice and throwing things at the wall hoping something sticks is far far worse than saying silent. Paul Lalli
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.