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

Hey Monks,

I've got some code smell and I can't find the right cleaner. I'm looking to combine the following two functions. I ended up writing them real quick to get another module finished, but I don't like the repitition. I've got a feeling that I'm not really being pragmatic or not using the right tools. Without further ado:

# Simple num item in list check sub is_in_num { my ($item, $l1) = @_; foreach my $e1 (@$l1) { if ($e1 == $item) { return 1; } } return 0; } # Simple str item in list check sub is_in_str { my ($item, $l1) = @_; foreach my $e1 (@$l1) { if ($e1 eq $item) { return 1; } } return 0; }

Did a bit of searching and didn't find any elegant solutions, but this is a pretty simple problem so maybe it doesn't demand such attention

Ransom

Replies are listed 'Best First'.
Re: Better way to write these checks?
by moritz (Cardinal) on Jun 29, 2012 at 12:38 UTC
      Thanks for the link. I think that's what I needed to find for several issues in my code.
Re: Better way to write these checks?
by Anonymous Monk on Jun 29, 2012 at 12:42 UTC
      I like the smart matching operator. Haven't seen that one before. Thanks for the solutions!
Re: Better way to write these checks?
by Athanasius (Archbishop) on Jun 29, 2012 at 12:52 UTC

    See also the 2007 thread Equality checking for strings AND numbers, which may give you some useful ideas.

    And note the point raised there by BrowserUk:

    If your data can contain reals, you might want to think about whether 10.0 == 10.000000000000001, or not.

    and the replies by lin0 and halley on how to handle this issue.

    HTH,

    Athanasius <°(((><contra mundum

Re: Better way to write these checks?
by ww (Archbishop) on Jun 29, 2012 at 15:44 UTC
    + +, Ransom, for an effective solution in a well-written question... and to various others in this thread for alternate ideas.

    But, really, , responding to the title, the better way to write a check is to enter ww in the 'pay to the order of' section; your account balance in the word$ and number$ for the amount; and, of course sign the check on the bottom line.

    ps: Postdated checks accepted only for the current month.

Re: Better way to write these checks?
by uday_sagar (Scribe) on Jun 29, 2012 at 13:27 UTC

    Here is my code which takes inputs from command line.

    my ($item, @l1) = @ARGV; print ((grep $item eq $_ , @l1) ? "found" : "sorry");

    Inputs can be:

    $ perl code.pl 23 24 25 23 #outputs "found"

    $ perl code.pl perl monks are great #outputs "sorry"

      Is that same as the OPs code?

      Is @ARGV is a substitute for @_?

      Is print a substitute for return?

      Is a program a substitute for a subroutine?

        Is that same as the OPs code?
        No, it shows another technique of accomplishing the desired result.

        Is @ARGV is a substitute for @_?
        No. See perlvar. @ARGV holds the command line arguments given to the script, @_ holds the arguments given to the subroutine. Interestingly, operators like shift know to work on @_ inside subroutines and on @ARGV in the main execution block. So the following two scripts will show the same output:

        printf "Got %s!\n", shift while @ARGV;
        use subs qw(printfor); printfor @ARGV; sub printfor { my $f = shift; printf "Got %s!\n", shift while @_; }

        Is print a substitute for return?
        No. return is used inside subroutines to give back data to the calling code, print is used to generate output, which could be sent to the screen or a file handle, or it could be passed to function as another program's input using pipeline constructions. Among other things

        Is a program a substitute for a subroutine?
        Not really, although it's definitely possible to make another program do some work for you as if it were a subroutine. Shell scripting often works like that.

Re: Better way to write these checks?
by linuxkid (Sexton) on Jun 29, 2012 at 17:48 UTC
    If you are trying to find out if the scalar is in the array, use the ~~ operator.

    --linuxkid


    imrunningoutofideas.co.cc