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. | [reply] |
|
|
it works if i use join and ""
| [reply] |
|
|
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.
| [reply] [d/l] |
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 | [reply] [d/l] [select] |
|
|
thanks for that, however, could you explain the line
sub { $_[0] == $_[1] }
what is this doing?
CODE tags added by Arunbear | [reply] [d/l] |
|
|
Sure, I could do that for you.
Also, check out perlsub for a better explanation.
-Bryan
| [reply] [d/l] [select] |
|
|
Re: Is it possible to store an arthimetric operator in a variable?
by ikegami (Patriarch) 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";
}
| [reply] [d/l] |
Re: Is it possible to store an arthimetric operator in a variable?
by Adam (Vicar) on Jul 19, 2005 at 14:25 UTC
|
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.
| [reply] [d/l] |
|
|
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.
| [reply] [d/l] [select] |
|
|
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.
| [reply] |
|
|
|
|
|
|
|
For those curious, this is how I might do it using tie.
| [reply] [d/l] |
Re: Is it possible to store an arthimetric operator in a variable?
by anonymized user 468275 (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") ) {
| [reply] [d/l] |
|
|
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
| [reply] |
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
| [reply] [d/l] [select] |