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

Hi everyone!

I am having problems passing a $Scaler into a while() loop. Could someone people tell me what I am doing wrong?

#!/usr/local/bin/perl -w use strict; my @cut; my $cut; open (WORDS, 'data.txt') or die "Can't open employees2.txt: $!\n"; my @cols = qw('data.txt'); while (my $line = <WORDS>) { chomp $line; my @words = split /\s+/, $line; $cut = pop(@words); chomp; next if !/a/; next if !/e/; next if !/i/; next if !/o/; next if !/u/; print $_ . "\n"; } }

I want this program to print out a list of every word in the text file that has all five vowels.

Thank you for all help and advice!

-mox

Replies are listed 'Best First'.
Re: Passing a $Scaler into a while loop...
by bobf (Monsignor) on Oct 09, 2006 at 04:13 UTC

    First, that code won't compile. You have an unmatched right curly bracket.

    Do you get any warnings? I get a couple "Use of uninitialized value" warnings. Hint: add a few print statements. I don't think the value of $_ is what you think it is.

    I'm not sure why you need to declare $cut outside the scope of the loop. If there is a reason for doing it that way, it's not evident from the code you posted.

    Finally, you split the line into @words, but you only test one word for vowels. You'll need to loop over each element of @words if you want to test every word on the line.

    I hope this gives you a starting point. It sounds a bit like homework so I tried to err on the side of hints rather than handing you a solution outright.

      Thank you for the very helpful reply. It is good to have someone tell where to look for the problem rather than just give you the answer.

      Sounding like homework is right for a reason...

      The issue is that I am taking corses online with a twelve hour time diffence so any help is often ten hours in comming. This is not good with a deadline and a day job!

        Oh. bobf was right (smelling like homework).

        Do us a favor. If you're looking for pointers for homework, let us know that. Heck, if you're looking for answers for homework, let us know that, too. You're less likely to get answers either way. I appreciate that you state you're looking for pointers and not answers. But let us know that up front.



        --chargrill
        s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
Re: Passing a $Scaler into a while loop...
by chargrill (Parson) on Oct 09, 2006 at 04:14 UTC

    chinamox: FWIW, it can be a little tough to help without seeing your data.

    Try something like this:

    while( my $line = <DATA> ){ ... } ... __DATA__ sample input data

    Having said that, you've got a trailing }, so that's an issue.

    open (WORDS, 'data.txt') or die "Can't open employees2.txt: $!\n"; my @cols = qw('data.txt');

    I'm not sure what you're doing there - your error message ought to reflect the name of the file it's having trouble with. And your @cuts @cols array contains one element, a piece of text 'data.txt'. I don't think that's what you want. Also, your regexes are matching against $_, when you want them to match against $cut, the next element of @words.

    Finally, I've reformatted your code, made it compile, and looped through the words of each line (which you weren't doing), and left the "meat" of your "algorithm" in place. Though that could be cleaned up, too.

    #!/usr/local/bin/perl use strict; use warnings; while (my $line = <DATA>) { chomp $line; for my $cut( split /\s+/, $line ){ next if $cut !~ /a/; next if $cut !~ /e/; next if $cut !~ /i/; next if $cut !~ /o/; next if $cut !~ /u/; print "$cut\n"; } } __DATA__ sample line with words input more words thiswordhaseveryvoul so it should print butthisdoesnt nor do these

    Output:

    $ perl chinamox.pl thiswordhaseveryvoul

    HTH



    --chargrill
    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)

      Wow! Thanks for the excellent reply. I will clean up my code and use the __DATA__ from now on when I post.

        Using __DATA__ instead of external files is a really good start. For a few other related posting tricks take a look at I know what I mean. Why don't you?.


        DWIM is Perl's answer to Gödel
Re: Passing a $Scaler into a while loop...
by GrandFather (Saint) on Oct 09, 2006 at 04:10 UTC

    It may be that what you want is:

    while (defined (my $line = <WORDS>)) {

    which avoids issues with values for $line that evaluate to false in a boolean context.

    If that is not your problem then a better example would include some data like this:

    use strict; use warnings; while (<DATA>) { chomp; my @words = split /\s+/; while (@words) { $_ = shift @words; next if ! defined $_; next unless /a/ && /e/ && /i/ && /o/ && /u/; print "Matched: $_\n"; } } __DATA__ aeiou 0 nothing here aeiou again

    DWIM is Perl's answer to Gödel

      Are you using an old version of Perl? There's an implicit defined in the scalar readline assignment; test it with B::Deparse yourself if you don't believe me:

      $ perl -MO=Deparse while (my $line = <>) {} ^D while (defined(my $line = <ARGV>)) { (); }
      Thanks for the help!
Re: Passing a $Scaler into a while loop...
by cdarke (Prior) on Oct 09, 2006 at 08:23 UTC
    One other thing that the others seemed not to pick up on, probably because the line does not seem to have any functionality in this program:
    my @cols = qw('data.txt');
    You should not use quotes inside a qw(...) unless you actually want the quotes to be part of the data. qw will quote each item for you anyway.
      Thank you! *goes hunting for quotes*
Re: Passing a $Scaler into a while loop...
by Anonymous Monk on Oct 09, 2006 at 04:11 UTC
    Where is $Scaler?
      opps, I meant $cut... Sorry!