Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Is it possible to store an arthimetric operator in a variable?

by Anonymous Monk
on Jul 19, 2005 at 14:00 UTC ( #476097=perlquestion: print w/replies, xml ) Need Help??

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

Hi, Is it possible to store an arthimetric operator in a variable?
while (<>) { $num ="2"; $eq = "=="; /(\d+).*/; if ($num $eq $1) { print "match\n"; } }
The error i get is a "missing operator before $eq". Thanks

Edited by Arunbear: Changed title from 'operators', as per Monastery guidelines

Replies are listed 'Best First'.
Re: Is it possible to store an arthimetric operator in a variable?
by Transient (Hermit) on Jul 19, 2005 at 14:02 UTC
    you would need to eval that statement before it would actually work. You are trying to interpolate a variable and then interpolate the result of that variable.
      it works if i use join and ""
        It works as in how? It parses? Yes, of course it will parse, what it will not do is give you a valid answer. I could join( "", 2, $eq, 1 ) all day long, but that doesn't mean 2 equals 1! The only reason that is "true" is because the value is "2 eq 1" (the string), which is not undefined or "", so it evaluates to true.
Re: Is it possible to store an arthimetric operator in a variable?
by mrborisguy (Hermit) on Jul 19, 2005 at 14:08 UTC

    Depending on what you want to do, you could just make a sub that contains your operator. That way, you can avoid an 'eval'.

    while (<>) { $num ="2"; $eq = sub { $_[0] == $_[1] }; /(\d+).*/; if ($eq->( $num, $1 ) ) { print "match\n"; } }
    You may have to predefine your operators if you are doing something complicated.
    my $eq = sub { $_[0] == $_[1] }; my $lt = sub { $_[0] < $_[1] }; # ... while (<>) { $num ="2"; if ( ...some logic... ) { $op = $eq; } else { $op = $lt; } $eq = sub { $_[0] == $_[1] }; /(\d+).*/; if ($op->( $num, $1 ) ) { print "match\n"; } }

        -Bryan

      thanks for that, however, could you explain the line
      sub { $_[0] == $_[1] }
      what is this doing?

      CODE tags added by Arunbear

        Sure, I could do that for you.

        Also, check out perlsub for a better explanation.

            -Bryan

Re: Is it possible to store an arthimetric operator in a variable?
by ikegami (Pope) on Jul 19, 2005 at 14:51 UTC

    Alternatively, you can use a dispatch table. It's very similar to the solution already provided, except that $op can now be displayed and serialized.

    my %ops = ( '==' => sub { $_[0] == $_[1] }, '<' => sub { $_[0] < $_[1] }, ); ... if (...) { $op = '=='; } else { $op = '<'; } ... if ($ops{$op}->($num1, $num2)) { print("$num1 $op $num2\n"; } else { print("$num1 not $op $num2\n"; }
Re: Is it possible to store an arthimetric operator in a variable?
by Adam (Vicar) on Jul 19, 2005 at 14:25 UTC
    Sure:
    sub _eq($$){ $_[0] == $_[1] ? 1 : 0 } sub _ne($$){ $_[0] == $_[1] ? 0 : 1 } my $op = \&_eq; print $op->( 1, 2 ) ? 'EQ' : 'NEQ'";
    Edit: mrborisguy beat me to this answer while I was contemplating using tie to do it.

      You shouldn't use prototypes unless necessary, because of their side-effects. In this case, the prototype isn't even being checked because you're using a reference to the function.

      And why bother with ?1:0 and ?0:1 since == already returns a boolean value.

        You are correct that the code isn't using the prototypes or requires the 1:0. I used them both, however, to be very clear to our anonymous reader what it was the code was doing. Also, I used 1:0 because I don't like using undef as a boolean false; it's not relevant here, but I find that 0 as false makes debugging easier which has led to this habit.
      For those curious, this is how I might do it using tie.
Re: Is it possible to store an arthimetric operator in a variable?
by (anonymized user) (Curate) on Jul 19, 2005 at 14:55 UTC
    As transient said, eval offers the most straightforward answer to what was asked; so to put this into your code:
    if ( eval ( "$num $eq $1") ) {

    One world, one people

      It is worth mentioning that one shouldn't eval user-supplied strings until they have been checked for safety (untainted). If a user is supplying the value for $eq, they could supply Perl code that would be executed: obviously, that's potentially dangerous.

      <-radiant.matrix->
      Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
      The Code that can be seen is not the true Code
Re: Is it possible to store an arthimetric operator in a variable?
by QM (Parson) on Jul 19, 2005 at 17:45 UTC
    Taking the tack that you may have given an oversimplified problem statement, would this do what you intended?
    $num = 2; while (<>) { if ( /(\A|\D)$num(\D|\Z)/ ) { print "match\n"; } }
    Here (\A|\D) matches the start of the string, or a non-digit. Likewise, (\D|\Z) matches a non-digit or the end of the string.

    If you have rules for what surrounds your $num value in the input string, you may better limit your search.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://476097]
Approved by Corion
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2019-10-21 04:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?